From b05feba70620a95b34121b57904bf60a875d566c Mon Sep 17 00:00:00 2001 From: GianlucaFuwa Date: Tue, 10 Dec 2024 18:08:24 +0100 Subject: [PATCH] Add cooling and ability to use multiple flow integrators --- MetaAnalysis/src/measurements.jl | 2 +- src/bias/Bias.jl | 2 +- src/main/Main.jl | 2 +- src/main/Universe.jl | 4 +- src/main/runbuild.jl | 9 +- src/main/runsim.jl | 98 +++++---- src/measurements/Measurements.jl | 3 +- src/measurements/measure_energy_density.jl | 7 +- src/measurements/measure_gauge_action.jl | 9 +- src/measurements/measure_pion_correlator.jl | 5 +- src/measurements/measure_plaquette.jl | 7 +- src/measurements/measure_polyakov.jl | 7 +- .../measure_topological_charge.jl | 7 +- src/measurements/measure_wilson_loop.jl | 5 +- src/measurements/measurement_methods.jl | 48 +++-- src/parameters/Parameters.jl | 198 ++++++++---------- src/parameters/parameter_set.jl | 2 +- src/parameters/parameter_structs.jl | 8 +- src/smearing/Smearing.jl | 38 +++- src/smearing/gradientflow.jl | 21 +- src/smearing/stout.jl | 2 +- src/updates/heatbath.jl | 2 +- src/updates/hmc.jl | 2 +- src/updates/metropolis.jl | 2 +- src/utils/Utils.jl | 7 +- 25 files changed, 267 insertions(+), 230 deletions(-) diff --git a/MetaAnalysis/src/measurements.jl b/MetaAnalysis/src/measurements.jl index 95e804a..f956402 100644 --- a/MetaAnalysis/src/measurements.jl +++ b/MetaAnalysis/src/measurements.jl @@ -21,7 +21,7 @@ struct MetaMeasurements """ ensemblename else - path = joinpath(splitpath(@__DIR__())[1:end-2]...) * "/ensembles/$(ensemblename)/measurements/" + path = joinpath(splitpath(@__DIR__())[1:end-2]...) * "/ensembles/$(ensemblename)/" @assert isdir(path) """ Ensemble \"$(ensemblename)\" could not be found or doesn't exist. """ diff --git a/src/bias/Bias.jl b/src/bias/Bias.jl index cea5cc0..d6e0b3c 100644 --- a/src/bias/Bias.jl +++ b/src/bias/Bias.jl @@ -52,7 +52,7 @@ function Bias(p::ParameterSet, U; mpi_multi_sim=false, instance=mpi_myrank(), du else instance end - @level1("- Setting Bias instance $(inum)...") + @level1("- Constructing Bias instance $(inum)...") kind_of_bias = Unicode.normalize(p.kind_of_bias; casefold=true) TCV = get_cvtype_from_parameters(p) smearing = StoutSmearing(U; numlayers=p.numsmears_for_cv, rho=p.rhostout_for_cv) diff --git a/src/main/Main.jl b/src/main/Main.jl index e6859a6..60ab216 100644 --- a/src/main/Main.jl +++ b/src/main/Main.jl @@ -13,7 +13,7 @@ import ..Fields: calc_gauge_action, is_distributed, normalize! import ..Measurements: MYEXT_str import ..Measurements: MeasurementMethods, calc_measurements, calc_measurements_flowed import ..Parameters: ParameterSet, construct_params_from_toml -import ..Smearing: GradientFlow +import ..Smearing: construct_flow import ..Universe: Univ import ..Updates: HMC, ParityUpdate, Updatemethod, update!, temper!, integrator_from_str import ..Updates: set_instanton! diff --git a/src/main/Universe.jl b/src/main/Universe.jl index 892aefb..ed6472d 100644 --- a/src/main/Universe.jl +++ b/src/main/Universe.jl @@ -31,7 +31,7 @@ struct Univ{TG,TF,TB} function Univ( U::Gaugefield{BACKEND,T,M,A,GA}, fermion_action::TF, bias::TB, numinstances ) where {BACKEND,T,M,A,GA,TF,TB} - @level1("- Setting Universe...") + @level1("- Constructing Universe...") @level1("| NUM INSTANCES: $(numinstances)") @level1("| BACKEND: $(string(BACKEND))") @level1("| FP PREC: $(string(T))") @@ -53,7 +53,7 @@ struct Univ{TG,TF,TB} function Univ( U::Vector{TG}, fermion_action::TF, bias::Vector{TB}, numinstances ) where {B,T,M,A,GA,TG<:Gaugefield{B,T,M,A,GA},TF,TB} - @level1("- Setting Universe...") + @level1("- Constructing Universe...") @level1("| NUM INSTANCES: $(numinstances)") @level1("| BACKEND: $(string(B))") @level1("| FP PREC: $(string(T))") diff --git a/src/main/runbuild.jl b/src/main/runbuild.jl index e74ca00..6d3e9fa 100644 --- a/src/main/runbuild.jl +++ b/src/main/runbuild.jl @@ -73,14 +73,7 @@ function build_bias!(univ, parameters, updatemethod; mpi_multi_sim=false) updatemethod = Updatemethod(parameters, U) end - gflow = GradientFlow( - U; - integrator=parameters.flow_integrator, - numflow=parameters.flow_num, - steps=parameters.flow_steps, - tf=parameters.flow_tf, - measure_every=parameters.flow_measure_every, - ) + gflow = construct_flow(U, parameters) additional_string = "_$(lpad(mpi_myrank(), 3, "0")).txt" diff --git a/src/main/runsim.jl b/src/main/runsim.jl index b35a46a..85758f1 100644 --- a/src/main/runsim.jl +++ b/src/main/runsim.jl @@ -138,31 +138,17 @@ function run_sim!(univ, parameters, updatemethod, updatemethod_pt; mpi_multi_sim parity = parameters.parity_update ? ParityUpdate(U) : nothing end - if parameters.tempering_enabled && !mpi_multi_sim - gflow = GradientFlow( - U[1]; - integrator=parameters.flow_integrator, - numflow=parameters.flow_num, - steps=parameters.flow_steps, - tf=parameters.flow_tf, - measure_every=parameters.flow_measure_every, - ) - measurements = Vector{MeasurementMethods}(undef, parameters.numinstances) - measurements_with_flow = Vector{MeasurementMethods}(undef, parameters.numinstances) + numinstances = parameters.numinstances + if parameters.tempering_enabled && !mpi_multi_sim + gflow = construct_flow(U[1], parameters) + measurements = Vector{MeasurementMethods}(undef, numinstances) measurements[1] = MeasurementMethods( U[1], parameters.measure_dir, parameters.measurements; additional_string="_000.txt", ) - measurements_with_flow[1] = MeasurementMethods( - U[1], - parameters.measure_dir, - parameters.measurements_with_flow; - flow=true, - additional_string="_000.txt", - ) - for i in 2:(parameters.numinstances) + for i in 2:numinstances if parameters.measure_on_all measurements[i] = MeasurementMethods( U[i], @@ -170,42 +156,50 @@ function run_sim!(univ, parameters, updatemethod, updatemethod_pt; mpi_multi_sim parameters.measurements; additional_string = "_$(lpad(i-1, 3, "0")).txt" ) - measurements_with_flow[i] = MeasurementMethods( - U[i], - parameters.measure_dir, - parameters.measurements_with_flow; - flow=true, - additional_string = "_$(lpad(i-1, 3, "0")).txt" - ) else - measurements[i] = MeasurementMethods( - U[i], parameters.measure_dir, Dict[]; - additional_string="_$(lpad(i-1, 3, "0")).txt" - ) - measurements_with_flow[i] = MeasurementMethods( - U[i], parameters.measure_dir, Dict[]; - additional_string="_$(lpad(i-1, 3, "0")).txt" - ) + measurements[i] = MeasurementMethods(U[i], parameters.measure_dir, Dict[]) end end - else - gflow = GradientFlow( - U; - integrator=parameters.flow_integrator, - numflow=parameters.flow_num, - steps=parameters.flow_steps, - tf=parameters.flow_tf, - measure_every=parameters.flow_measure_every, - ) + measurements_with_flow = ntuple(length(gflow)) do i + _measurements_with_flow = Vector{MeasurementMethods}(undef, numinstances) + _measurements_with_flow[1] = MeasurementMethods( + U[1], + parameters.measure_dir, + parameters.measurements_with_flow; + flow=gflow[i], + additional_string="_000.txt", + ) + + for j in 2:numinstances + if parameters.measure_on_all + _measurements_with_flow[j] = MeasurementMethods( + U[j], + parameters.measure_dir, + parameters.measurements_with_flow; + flow=gflow[i], + additional_string = "_$(lpad(j-1, 3, "0")).txt" + ) + else + measure_dir = parameters.measure_dir + _measurements_with_flow[i] = MeasurementMethods(U[i], measure_dir, Dict[]) + end + end + + _measurements_with_flow + end + else + gflow = construct_flow(U, parameters) measurements = MeasurementMethods( U, parameters.measure_dir, parameters.measurements; additional_string="_$(lpad(mpi_myrank(), 3, "0")).txt" ) - measurements_with_flow = MeasurementMethods( - U, parameters.measure_dir, parameters.measurements_with_flow; - flow=true, additional_string="_$(lpad(mpi_myrank(), 3, "0")).txt" - ) + measurements_with_flow = ntuple(length(gflow)) do i + MeasurementMethods( + U, parameters.measure_dir, parameters.measurements_with_flow; + flow=gflow[i], additional_string="_$(lpad(mpi_myrank(), 3, "0")).txt" + ) + end end # initialize functor responsible for saving gaugefield configurations @@ -345,10 +339,12 @@ function metaqcd!( _, mtime = @timed calc_measurements( measurements, U, itrj, myinstance[]; mpi_multi_sim=mpi_multi_sim ) - _, fmtime = @timed calc_measurements_flowed( - measurements_with_flow, gflow, U, itrj, myinstance[]; - mpi_multi_sim=mpi_multi_sim - ) + _, fmtime = @timed for i in eachindex(gflow) + calc_measurements_flowed( + measurements_with_flow[i], gflow[i], U, itrj, myinstance[]; + mpi_multi_sim=mpi_multi_sim + ) + end calc_weights(bias, U.CV, itrj, myinstance[]; mpi_multi_sim=mpi_multi_sim) @level1("| Meas. elapsed time: $(mtime) [s]") @level1("| FlowMeas. elapsed time: $(fmtime) [s]\n-") diff --git a/src/measurements/Measurements.jl b/src/measurements/Measurements.jl index 217d970..7a6c446 100644 --- a/src/measurements/Measurements.jl +++ b/src/measurements/Measurements.jl @@ -28,7 +28,8 @@ import ..Fields: Gaugefield, Spinorfield, calc_gauge_action, check_dims, clover_ import ..Fields: clover_square, global_dims, local_dims, float_type, plaquette, wilsonloop import ..Fields: @groupreduce, @latsum, Plaquette, Clover, Improved, CPU, ones!, set_source! import ..Fields: distributed_reduce, is_distributed, plaquette_trace_sum, wilsonloop -import ..Smearing: StoutSmearing, calc_smearedU!, flow! +import ..Smearing: AbstractSmearing, Cooling, GradientFlow, NoSmearing, StoutSmearing +import ..Smearing: calc_smearedU!, flow! abstract type AbstractMeasurement end diff --git a/src/measurements/measure_energy_density.jl b/src/measurements/measure_energy_density.jl index 9228cc8..b27aa0a 100644 --- a/src/measurements/measure_energy_density.jl +++ b/src/measurements/measure_energy_density.jl @@ -2,7 +2,7 @@ struct EnergyDensityMeasurement{T} <: AbstractMeasurement ED_dict::Dict{String,Float64} # energy density definition => value filename::T function EnergyDensityMeasurement( - U::Gaugefield; filename="", ED_methods=["clover"], flow=false + U::Gaugefield; filename="", ED_methods=["clover"], flow=NoSmearing() ) ED_dict = Dict{String,Float64}() @@ -28,7 +28,7 @@ struct EnergyDensityMeasurement{T} <: AbstractMeasurement rpath = StaticString(filename) header = "" - if flow + if flow == true || flow != NoSmearing() header *= @sprintf("%-11s%-7s%-9s", "itrj", "iflow", "tflow") else header *= @sprintf("%-11s", "itrj") @@ -68,6 +68,7 @@ function measure( itrj=0, flow=nothing; mpi_multi_sim=false, + fstr="", ) where {T} ED_dict = m.ED_dict iflow, τ = isnothing(flow) ? (0, 0.0) : flow @@ -81,7 +82,7 @@ function measure( E = ED_dict[method] if !isnothing(flow) - @level1("$itrj\t$E # energydensity_$(method)_flow_$(iflow)") + @level1("$itrj\t$E # energydensity_$(method)$(fstr)_$(iflow)") else @level1("$itrj\t$E # energydensity_$(method)") end diff --git a/src/measurements/measure_gauge_action.jl b/src/measurements/measure_gauge_action.jl index cf9bd6f..6fa2f77 100644 --- a/src/measurements/measure_gauge_action.jl +++ b/src/measurements/measure_gauge_action.jl @@ -2,7 +2,9 @@ struct GaugeActionMeasurement{T} <: AbstractMeasurement GA_dict::Dict{String,Float64} # gauge action definition => value factor::Float64 # 1 / (6*U.NV*U.β) filename::T - function GaugeActionMeasurement(U; filename="", GA_methods=["wilson"], flow=false) + function GaugeActionMeasurement( + U; filename="", GA_methods=["wilson"], flow=NoSmearing() + ) GA_dict = Dict{String,Float64}() for method in GA_methods @@ -14,7 +16,7 @@ struct GaugeActionMeasurement{T} <: AbstractMeasurement rpath = StaticString(filename) header = "" - if flow + if flow == true || flow == NoSmearing() header *= @sprintf("%-11s%-7s%-9s", "itrj", "iflow", "tflow") else header *= @sprintf("%-11s", "itrj") @@ -55,6 +57,7 @@ function measure( itrj=0, flow=nothing; mpi_multi_sim=false, + fstr="", ) where {T} GA_dict = m.GA_dict iflow, τ = isnothing(flow) ? (0, 0.0) : flow @@ -68,7 +71,7 @@ function measure( S = GA_dict[method] if !isnothing(flow) - @level1("$itrj\t$S # gaction_$(method)_flow_$(iflow)") + @level1("$itrj\t$S # gaction_$(method)$(fstr)_$(iflow)") else @level1("$itrj\t$S # gaction_$(method)") end diff --git a/src/measurements/measure_pion_correlator.jl b/src/measurements/measure_pion_correlator.jl index b599b01..3629b36 100644 --- a/src/measurements/measure_pion_correlator.jl +++ b/src/measurements/measure_pion_correlator.jl @@ -12,7 +12,7 @@ struct PionCorrelatorMeasurement{T,TD,TF,CT} <: AbstractMeasurement filename="", dirac_type="wilson", eo_precon=false, - flow=false, + flow=NoSmearing(), mass=0.1, csw=0, r=1, @@ -58,7 +58,7 @@ struct PionCorrelatorMeasurement{T,TD,TF,CT} <: AbstractMeasurement rpath = StaticString(filename) header = "" - if flow + if flow == true || flow == NoSmearing() header *= @sprintf("%-11s%-7s%-9s", "itrj", "iflow", "tflow") else header *= @sprintf("%-11s", "itrj") @@ -111,6 +111,7 @@ function measure( itrj=0, flow=nothing; mpi_multi_sim=false, + kwargs..., ) where {T} pion_correlators_avg!( m.pion_corr, m.dirac_operator(U), m.temp, m.cg_temps, m.cg_tol, m.cg_maxiters diff --git a/src/measurements/measure_plaquette.jl b/src/measurements/measure_plaquette.jl index 5478aa9..7c8785d 100644 --- a/src/measurements/measure_plaquette.jl +++ b/src/measurements/measure_plaquette.jl @@ -1,12 +1,12 @@ struct PlaquetteMeasurement{T} <: AbstractMeasurement factor::Float64 # 1 / (6*U.NV*U.NC) filename::T - function PlaquetteMeasurement(U::Gaugefield; filename="", flow=false) + function PlaquetteMeasurement(U::Gaugefield; filename="", flow=NoSmearing()) if !isnothing(filename) && filename != "" rpath = StaticString(filename) header = "" - if flow + if flow == true || flow == NoSmearing() header *= @sprintf( "%-11s%-7s%-9s%-25s", "itrj", "iflow", "tflow", "Re(plaq)" ) @@ -40,13 +40,14 @@ function measure( itrj=0, flow=nothing; mpi_multi_sim=false, + fstr="", ) where {T} plaq = plaquette_trace_sum(U) * m.factor iflow, τ = isnothing(flow) ? (0, 0.0) : flow if !is_distributed(U) || mpi_amroot() if !isnothing(flow) - @level1("$itrj\t$plaq # plaq_flow_$(τ)") + @level1("$itrj\t$plaq # plaq$(fstr)_$(τ)") else @level1("$itrj\t$plaq # plaq") end diff --git a/src/measurements/measure_polyakov.jl b/src/measurements/measure_polyakov.jl index 6336c3b..fbbbda9 100644 --- a/src/measurements/measure_polyakov.jl +++ b/src/measurements/measure_polyakov.jl @@ -1,6 +1,6 @@ struct PolyakovMeasurement{T} <: AbstractMeasurement filename::T - function PolyakovMeasurement(U::Gaugefield; filename="", flow=false) + function PolyakovMeasurement(U::Gaugefield; filename="", flow=NoSmearing()) if is_distributed(U) @assert U.topology.numprocs_cart[4] == 1 "Field cannot be decomposed in time direction for polykov loop calculation" end @@ -9,7 +9,7 @@ struct PolyakovMeasurement{T} <: AbstractMeasurement rpath = StaticString(filename) header = "" - if flow + if flow == true || flow == NoSmearing() header *= @sprintf( "%-11s%-7s%-9s%-25s%-25s", "itrj", @@ -47,13 +47,14 @@ function measure( itrj=0, flow=nothing; mpi_multi_sim=false, + fstr="", ) where {T} poly = polyakov_traced(U) iflow, τ = isnothing(flow) ? (0, 0.0) : flow if !is_distributed(U) || mpi_amroot() if !isnothing(flow) - @level1("$itrj\t$(real(poly)) + $(imag(poly))im # poly_flow_$(τ)") + @level1("$itrj\t$(real(poly)) + $(imag(poly))im # poly$(fstr)_$(τ)") else @level1("$itrj\t$(real(poly)) + $(imag(poly))im # poly") end diff --git a/src/measurements/measure_topological_charge.jl b/src/measurements/measure_topological_charge.jl index 75444e1..1417984 100644 --- a/src/measurements/measure_topological_charge.jl +++ b/src/measurements/measure_topological_charge.jl @@ -2,7 +2,7 @@ struct TopologicalChargeMeasurement{T} <: AbstractMeasurement TC_dict::Dict{String,Float64} # topological charge definition => value filename::T function TopologicalChargeMeasurement( - U::Gaugefield; filename="", TC_methods=["clover"], flow=false + U::Gaugefield; filename="", TC_methods=["clover"], flow=NoSmearing() ) TC_dict = Dict{String,Float64}() @@ -28,7 +28,7 @@ struct TopologicalChargeMeasurement{T} <: AbstractMeasurement rpath = StaticString(filename) header = "" - if flow + if flow == true || flow != NoSmearing() header *= @sprintf("%-11s%-7s%-9s", "itrj", "iflow", "tflow") else header *= @sprintf("%-11s", "itrj") @@ -70,6 +70,7 @@ function measure( itrj=0, flow=nothing; mpi_multi_sim=false, + fstr="", ) where {T} TC_dict = m.TC_dict iflow, τ = isnothing(flow) ? (0, 0.0) : flow @@ -83,7 +84,7 @@ function measure( Q = TC_dict[method] if !isnothing(flow) - @level1("$itrj\t$Q # topcharge_$(method)_flow_$(τ)") + @level1("$itrj\t$Q # topcharge_$(method)$(fstr)_$(τ)") else @level1("$itrj\t$Q # topcharge_$(method)") end diff --git a/src/measurements/measure_wilson_loop.jl b/src/measurements/measure_wilson_loop.jl index 7ddfe8b..0a22171 100644 --- a/src/measurements/measure_wilson_loop.jl +++ b/src/measurements/measure_wilson_loop.jl @@ -4,7 +4,7 @@ struct WilsonLoopMeasurement{T} <: AbstractMeasurement Rmax::Int64 # maximum length of the Wilson loop filename::T function WilsonLoopMeasurement( - U::Gaugefield; filename="", Rmax=4, Tmax=4, flow=false + U::Gaugefield; filename="", Rmax=4, Tmax=4, flow=NoSmearing() ) @assert !is_distributed(U) "Wilson loop not supported for distributed fields" @level1("| Maximum Extends: $Tmax x $Rmax (only even extends are measured for now)") @@ -15,7 +15,7 @@ struct WilsonLoopMeasurement{T} <: AbstractMeasurement rpath = StaticString(filename) header = "" - if flow + if flow == true || flow == NoSmearing() header *= @sprintf("%-11s%-7s%-9s", "itrj", "iflow", "tflow") else header *= @sprintf("%-11s", "itrj") @@ -58,6 +58,7 @@ function measure( itrj=0, flow=nothing; mpi_multi_sim=false, + kwargs..., ) where {T} iflow, τ = isnothing(flow) ? (0, 0.0) : flow diff --git a/src/measurements/measurement_methods.jl b/src/measurements/measurement_methods.jl index bd997e2..327352a 100644 --- a/src/measurements/measurement_methods.jl +++ b/src/measurements/measurement_methods.jl @@ -7,16 +7,22 @@ end @inline Base.getindex(m::MeasurementMethods{M}, i) where {M} = m.measurements[i] @inline Base.eachindex(m::MeasurementMethods{M}) where {M} = Base.OneTo(length(m.measurements)) +@inline flow_string(::Nothing) = "" +@inline flow_string(::NoSmearing) = "" +@inline flow_string(::GradientFlow) = "_gflow" +@inline flow_string(::Cooling) = "_cooling" function MeasurementMethods( - U, measurement_dir, measurement_methods::Vector{Dict}; flow=false, additional_string="" + U, measurement_dir, measurement_methods::Vector{Dict}; + flow=NoSmearing(), additional_string="", ) - @level1("- Preparing $(ifelse(flow, "flowed", "")) Measurements...") + fstr = flow_string(flow) + @level1("- Preparing $(fstr) Measurements...") num_measurements = length(measurement_methods) # measurement_parameters_set = Vector{MeasurementParameters}(undef, num_measurements) intervals = zeros(Int64, num_measurements) - add_string = (flow ? "_flowed" : "") * additional_string + add_string = fstr * additional_string measurements = ntuple(num_measurements) do i measurement_parameters = meas_parameters_from_dict(measurement_methods[i]) @@ -64,42 +70,56 @@ function calc_measurements( return nothing end +calc_measurements_flowed(::Any, ::NoSmearing, args...; kwargs...) = nothing + function calc_measurements_flowed( - m::Vector{MeasurementMethods}, gflow, U, itrj, measure_on_all=false; kwargs... + m::Vector{MeasurementMethods}, flow, U, itrj, measure_on_all=false; kwargs... ) if measure_on_all # if we measure on all streams in PT-MetaD for i in eachindex(m) - calc_measurements_flowed(m[i], gflow, U[i], itrj, i-1) + calc_measurements_flowed(m[i], flow, U[i], itrj, i-1) end else - calc_measurements_flowed(m[1], gflow, U[1], itrj, 0) + calc_measurements_flowed(m[1], flow, U[1], itrj, 0) + end + + return nothing +end + + +function calc_measurements_flowed( + m::MeasurementMethods, flow::Tuple, U, itrj, myinstance=mpi_myrank(); + mpi_multi_sim=false +) + for f in flow + calc_measurements_flowed(m, f, U, itrj, myinstance; mpi_multi_sim=mpi_multi_sim) end return nothing end function calc_measurements_flowed( - m::MeasurementMethods, gradient_flow, U, itrj, myinstance=mpi_myrank(); + m::MeasurementMethods, flow::AbstractSmearing, U, itrj, myinstance=mpi_myrank(); mpi_multi_sim=false ) # check if the current iteration has any measurements to be made to avoid work check_for_measurements(itrj, m.intervals) || return nothing - copy!(gradient_flow.Uflow, U) - tf = gradient_flow.tf + copy!(flow.Uflow, U) + tf = flow.tf - for iflow in 1:(gradient_flow.numflow) - flow!(gradient_flow) - Uflow = gradient_flow.Uflow + for iflow in 1:(flow.numflow) + flow!(flow) + Uflow = flow.Uflow τ = iflow * tf - if iflow ∈ gradient_flow.measure_at + if iflow ∈ flow.measure_at for i in 1:(m.num_measurements) interval = m.intervals[i] if itrj%interval == 0 measure( m.measurements[i], Uflow, myinstance, itrj, (iflow, τ); - mpi_multi_sim=mpi_multi_sim + mpi_multi_sim=mpi_multi_sim, fstr=flow_string(flow) ) end end diff --git a/src/parameters/Parameters.jl b/src/parameters/Parameters.jl index f359d5b..fed7a32 100644 --- a/src/parameters/Parameters.jl +++ b/src/parameters/Parameters.jl @@ -10,8 +10,6 @@ include("./parameter_set.jl") export ParameterSet -lower_case(str) = Unicode.normalize(str; casefold=true) - function set_params_value!(value_Params, values) d = struct2dict(values) pnames = fieldnames(ParameterSet) @@ -180,6 +178,12 @@ function construct_params_from_toml(parameters, inputfile; backend="cpu") value_Params[i] = valuedir elseif String(pname_i) == "L" value_Params[i] = Tuple(value[String(pname_i)]) + elseif String(pname_i) == "flow_integrator" + if value[String(pname_i)] isa String + value_Params[i] = [value[String(pname_i)]] + else + value_Params[i] = value[String(pname_i)] + end elseif String(pname_i) == "rhmc_spectral_bound" value_Params[i] = Tuple(value[String(pname_i)]) elseif String(pname_i) == "is_static" @@ -255,129 +259,111 @@ function check_parameters(p::ParameterSet) @assert length(p.starting_Q) == mpi_size() end - if lower_case(p.gauge_action) ∉ ["wilson", "iwasaki", "symanzik_tree", "dbw2"] - ga = p.gauge_action - throw(AssertionError(""" - gauge_action in [\"Physical Settings\"] = $(ga) is not supported. - Supported gactions are: - Wilson - Iwasaki - DBW2 - Symanzik_tree - """)) - end + @assert lower_case(p.gauge_action) ∈ ["wilson", "iwasaki", "symanzik_tree", "dbw2"] """ + gauge_action in [\"Physical Settings\"]: \"$(p.gauge_action)\" is not supported. + Supported gactions are: + Wilson + Iwasaki + DBW2 + Symanzik_tree + """ - if lower_case(p.fermion_action) ∉ [ + @assert lower_case(p.fermion_action) ∈ [ "none", "wilson", "staggered", "staggered-h1234", "staggered-h1324", "staggered-h1342" - ] - fa = p.fermion_action - throw(AssertionError(""" - fermion_action in [\"Physical Settings\"] = $(fa) is not supported. - Supported gactions are: - None - Wilson - Staggered - Staggered-H1234 - Staggered-H1324 - Staggered-H1342 - """)) - end + ] """ + fermion_action in [\"Physical Settings\"]: \"$(p.fermion_action)\" is not supported. + Supported gactions are: + None + Wilson + Staggered + Staggered-H1234 + Staggered-H1324 + Staggered-H1342 + """ if lower_case(p.fermion_action) != "none" @assert lower_case(p.update_method) == "hmc" "Dynamical fermions only with HMC" end - if lower_case(p.initial) ∉ ["cold", "hot"] - throw(AssertionError(""" - intial in [\"Physical Settings\"] = $(p.initial) is not supported. - Supported initial conditions are: - cold - hot - """)) - end + @assert lower_case(p.initial) ∈ ["cold", "hot"] """ + intial in [\"Physical Settings\"]: \"$(p.initial)\" is not supported. + Supported initial conditions are: + cold + hot + """ - if lower_case(p.update_method) ∉ ["hmc", "metropolis", "heatbath"] - um = p.update_method - throw(AssertionError(""" - update_method in [\"Physical Settings\"] = $(um) is not supported. - Supported methods are: - HMC - Metropolis - Heatbath - """)) - end + @assert lower_case(p.update_method) ∈ ["hmc", "metropolis", "heatbath"] """ + update_method in [\"Physical Settings\"]: \"$(p.update_method)\" is not supported. + Supported methods are: + HMC + Metropolis + Heatbath + """ - if lower_case(p.hmc_integrator) ∉ [ + @assert lower_case(p.hmc_integrator) ∈ [ "leapfrog", "omf2slow", "omf2", "omf4slow", "omf4", "leapfrogra", "omf4ra" - ] - throw(AssertionError(""" - hmc_integrator in [\"HMC Settings\"] = $(p.hmc_integrator) is not supported. - Supported methods are: - Leapfrog - LeapfrogRA - OMF2Slow - OMF2 - OMF4Slow - OMF4 - """)) - end + ] """ + hmc_integrator in [\"HMC Settings\"]: \"$(p.hmc_integrator)\" is not supported. + Supported methods are: + Leapfrog + LeapfrogRA + OMF2Slow + OMF2 + OMF4Slow + OMF4 + OMF4RA + """ - if lower_case(p.kind_of_bias) ∉ ["none", "metad", "metadynamics", "opes", "parametric"] - throw(AssertionError(""" - kind_of_bias in [\"Bias Settings\"] = $(p.kind_of_bias) is not supported. - Supported biases are: - None - Metadynamics/MetaD - OPES - Parametric - """)) - end + @assert lower_case(p.kind_of_bias) ∈ [ + "none", "metad", "metadynamics", "opes", "parametric" + ] """ + kind_of_bias in [\"Bias Settings\"]: \"$(p.kind_of_bias)\" is not supported. + Supported biases are: + None + Metadynamics/MetaD + OPES + Parametric + """ - if lower_case(p.kind_of_cv) ∉ ["plaquette", "clover"] - throw(AssertionError(""" - kind_of_cv in [\"Bias Settings\"] = $(p.kind_of_cv) is not supported. - Supported biases are: - Plaquette - Clover - """)) - end + @assert lower_case(p.kind_of_cv) ∈ ["plaquette", "clover"] """ + kind_of_cv in [\"Bias Settings\"]: \"$(p.kind_of_cv)\" is not supported. + Supported biases are: + Plaquette + Clover + """ - if lower_case(p.flow_integrator) ∉ ["euler", "rk2", "rk3", "rk3w7"] - fi = p.flow_integrator - throw(AssertionError(""" - flow_integrator in [\"Gradient Flow Settings\"] = $(fi) is not supported. - Supported methods are: - Euler - RK2 - RK3 - RK3W7 - """)) + for flow_int in p.flow_integrator + @assert lower_case(flow_int) ∈ ["euler", "rk2", "rk3", "rk3w7", "cooling"] """ + flow_integrator in [\"Gradient Flow Settings\"]: \"$(flow_int)\" is not supported. + Supported methods are: + Euler + RK2 + RK3 + RK3W7 + Cooling + """ end - if lower_case(p.save_config_format) ∉ ["", "bmw", "bridge", "jld", "jld2"] - throw(AssertionError(""" - save_config_format in [\"System Settings\"] = $(p.save_config_format) \ - is not supported. - Supported methods are: - Bridge - JLD or JLD2 (both use JLD2) - BMW - """)) - end + @assert lower_case(p.save_config_format) ∈ ["", "bmw", "bridge", "jld", "jld2"] """ + save_config_format in [\"System Settings\"]: \"$(p.save_config_format)\" \ + is not supported. + Supported methods are: + Bridge + JLD or JLD2 (both use JLD2) + BMW + """ if p.load_config_fromfile @assert isfile(p.load_config_path) "Your load_config_path doesn't exist" - if lower_case(p.load_config_format) ∉ ["bmw", "bridge", "jld", "jld2"] - throw(AssertionError(""" - loadU_format in [\"System Settings\"] = $(p.load_config_format) \ - is not supported. - Supported methods are: - Bridge - JLD or JLD2 (both use JLD2) - BMW - """)) - end + @assert lower_case(p.load_config_format) ∈ ["bmw", "bridge", "jld", "jld2"] """ + loadU_format in [\"System Settings\"]: \"$(p.load_config_format)\" \ + is not supported. + Supported methods are: + Bridge + JLD or JLD2 (both use JLD2) + BMW + """ end return nothing diff --git a/src/parameters/parameter_set.jl b/src/parameters/parameter_set.jl index af1dfac..f8c53cd 100644 --- a/src/parameters/parameter_set.jl +++ b/src/parameters/parameter_set.jl @@ -95,7 +95,7 @@ struct ParameterSet # measurements measurements::Vector{Dict} measurements_with_flow::Vector{Dict} - flow_integrator::String + flow_integrator::Vector{String} flow_num::Int64 flow_tf::Float64 flow_steps::Int64 diff --git a/src/parameters/parameter_structs.jl b/src/parameters/parameter_structs.jl index 03418a6..4dd8b1c 100644 --- a/src/parameters/parameter_structs.jl +++ b/src/parameters/parameter_structs.jl @@ -100,10 +100,10 @@ Base.@kwdef mutable struct HMCParameters end Base.@kwdef mutable struct GradientFlowParameters - flow_integrator::String = "euler" - flow_num::Int64 = 1 - flow_tf::Float64 = 0.1 - flow_steps::Int64 = 10 + flow_integrator::String = "none" + flow_num::Int64 = 0 + flow_tf::Float64 = 0.0 + flow_steps::Int64 = 0 flow_measure_every::Union{Int64,Vector{Int64}} = 1 end diff --git a/src/smearing/Smearing.jl b/src/smearing/Smearing.jl index c684509..118b0ac 100644 --- a/src/smearing/Smearing.jl +++ b/src/smearing/Smearing.jl @@ -11,7 +11,7 @@ using ..Utils import ..Fields: AbstractGaugeAction, Expfield, Colorfield, Gaugefield, WilsonGaugeAction import ..Fields: check_dims, leftmul_dagg!, staple, staple_eachsite!, update_halo! -import ..Fields: AbstractField, dims, float_type, @groupreduce, @latmap +import ..Fields: AbstractField, dims, float_type, gauge_action, @groupreduce, @latmap abstract type AbstractSmearing end @@ -19,18 +19,35 @@ struct NoSmearing <: AbstractSmearing end include("./stout.jl") include("./gradientflow.jl") +include("./cooling.jl") include("gpu_kernels/gradientflow.jl") include("gpu_kernels/stout.jl") -function construct_smearing(U, smearingparameters, coefficient, numlayers) - if smearingparameters == "nothing" - smearing = NoSmearing() - elseif smearingparameters == "stout" - @assert coefficient !== nothing "Stout coefficient must be set" - println("Stout smearing will be used") - smearing = StoutSmearing(U; numlayers=numlayers, rho=coefficient) - else - error("Smearing = $smearing is not supported") +function construct_flow(U, parameters) + flow_integrator = lower_case.(parameters.flow_integrator) + + # can measure using multiple integrators in one simulation + smearing = ntuple(length(flow_integrator)) do i + if flow_integrator[i] == "none" + NoSmearing() + elseif flow_integrator[i] == "cooling" + Cooling( + U; + numflow=parameters.flow_num, + measure_every=parameters.flow_measure_every, + ) + elseif flow_integrator[i] ∈ ("euler", "rk2", "rk3", "rk3w7") + GradientFlow( + U; + integrator=parameters.flow_integrator[i], + numflow=parameters.flow_num, + steps=parameters.flow_steps, + tf=parameters.flow_tf, + measure_every=parameters.flow_measure_every, + ) + else + error("Flow integrator \"$(parameters.flow_integrator)\" is not supported") + end end return smearing @@ -38,5 +55,6 @@ end calc_smearedU!(smearing::StoutSmearing, Uin) = apply_smearing!(smearing, Uin) calc_smearedU!(smearing::GradientFlow, Uin) = flow!(smearing, Uin) +calc_smearedU!(smearing::Cooling, Uin) = flow!(smearing, Uin) end diff --git a/src/smearing/gradientflow.jl b/src/smearing/gradientflow.jl index d46ca9f..a8d1c9b 100644 --- a/src/smearing/gradientflow.jl +++ b/src/smearing/gradientflow.jl @@ -1,5 +1,14 @@ abstract type AbstractIntegrator end +""" + GradientFlow(U::Gaugefield; numflow=1, steps=1, tf=0.12, measure_every=1) + +Create a gradient flow struct that smears `numflow` times with a flow of `tf` and +a step size of `tf / steps`. When used in `calc_measurements_flowed` observables are +after every integer multiple of `measure_every * tf` if `measure_every` is a positive +integer and at `measure_every[i] * tf for i in eachindex(measure_every)` if `measure_every` +is a range. +""" struct GradientFlow{TI,TG,TT} <: AbstractSmearing numflow::Int64 steps::Int64 @@ -15,7 +24,9 @@ include("gradientflow_integrators.jl") function GradientFlow( U::TG; integrator="euler", numflow=1, steps=1, tf=0.12, measure_every=1 ) where {TG} - @level1("- Setting Gradient Flow...") + (numflow == 0 || tf == 0) && (return NoSmearing()) + + @level1("- Constructing Gradient Flow...") Z = Colorfield(U) Uflow = similar(U) @@ -50,11 +61,11 @@ function GradientFlow( return GradientFlow{TI,TG,typeof(Z)}(numflow, steps, ϵ, tf, measure_at, Uflow, Z) end -flow!(method::GradientFlow{TI}) where {TI} = flow!(TI(), method) +flow!(gflow::GradientFlow{TI}) where {TI} = flow!(TI(), gflow) -function flow!(method::GradientFlow{TI}, Uin) where {TI} - copy!(method.Uflow, Uin) - flow!(TI(), method) +function flow!(gflow::GradientFlow{TI}, Uin) where {TI} + copy!(gflow.Uflow, Uin) + flow!(TI(), gflow) return nothing end diff --git a/src/smearing/stout.jl b/src/smearing/stout.jl index 5e8999b..f679f80 100644 --- a/src/smearing/stout.jl +++ b/src/smearing/stout.jl @@ -1,5 +1,5 @@ """ - StoutSmearing(U::Gaugefield, numlayers, ρ) + StoutSmearing(U::Gaugefield; numlayers=0, rho=0) Struct StoutSmearing holds all fields relevant to smearing and subsequent recursion. \\ Since we never actually use the smeared fields in main, they dont have to leave this scope diff --git a/src/updates/heatbath.jl b/src/updates/heatbath.jl index 5e374b0..dba64aa 100644 --- a/src/updates/heatbath.jl +++ b/src/updates/heatbath.jl @@ -27,7 +27,7 @@ struct Heatbath{MAXIT,ITR,TOR,NHB,NOR} <: AbstractUpdate end function Heatbath( ::Gaugefield{B,T,A,GA}, MAXIT, numheatbath, or_alg, numorelax; kwargs... ) where {B,T,A,GA} - @level1("┌ Setting Heatbath...") + @level1("┌ Constructing Heatbath...") ITR = GA == WilsonGaugeAction ? Checkerboard2 : Checkerboard4 @level1("| ITERATOR: $(string(ITR))") diff --git a/src/updates/hmc.jl b/src/updates/hmc.jl index 22501ee..1a51b70 100644 --- a/src/updates/hmc.jl +++ b/src/updates/hmc.jl @@ -70,7 +70,7 @@ struct HMC{TI,TG,TT,TF,TSG,TSF,PO,F2,FS,TFP1,TFP2} <: AbstractUpdate integrator, steps, Δτ, friction, P, P_old, U_old, ϕ, staples, force, force2, fieldstrength, smearing_gauge, smearing_fermion, logfile, forcefile, ) - @level1("- Setting HMC...") + @level1("- Constructing HMC...") @level1("| INTEGRATOR: $(string(integrator))") @level1("| TRAJECTORY LENGTH: $(steps * Δτ)") @level1("| STEPS: $(steps)") diff --git a/src/updates/metropolis.jl b/src/updates/metropolis.jl index 5b45807..0f732ba 100644 --- a/src/updates/metropolis.jl +++ b/src/updates/metropolis.jl @@ -27,7 +27,7 @@ struct Metropolis{ITR,NH,TOR,NOR} <: AbstractUpdate function Metropolis( ::Gaugefield{B,T,A,GA}, ϵ, numhits, target_acc, or_alg, numorelax; kwargs... ) where {B,T,A,GA} - @level1("┌ Setting Metropolis...") + @level1("┌ Constructing Metropolis...") m_ϵ = Base.RefValue{Float64}(ϵ) ITR = (GA == WilsonGaugeAction) ? Checkerboard2 : Checkerboard4 diff --git a/src/utils/Utils.jl b/src/utils/Utils.jl index 8d17d38..23994fc 100644 --- a/src/utils/Utils.jl +++ b/src/utils/Utils.jl @@ -7,6 +7,7 @@ using MPI using MuladdMacro: @muladd using Polyester using Random +using Unicode using StaticArrays using StaticTools using PrecompileTools: PrecompileTools @@ -23,7 +24,7 @@ export embed_into_SU3_12, embed_into_SU3_13, embed_into_SU3_23 export antihermitian, hermitian, traceless_antihermitian, traceless_hermitian, materialize_TA export zero2, zero3, zerov3, eye2, eye3, onev3, gaussian_TA_mat, rand_SU3 export SiteCoords, eo_site, eo_site_switch, move, switch_sides -export cartesian_to_linear, set_ext! +export cartesian_to_linear, linear_to_cartesian, set_ext! export Sequential, Checkerboard2, Checkerboard4, EvenSites, OddSites export λ, expλ, γ1, γ2, γ3, γ4, γ5, σ12, σ13, σ14, σ23, σ24, σ34 export cmatmul_oo, cmatmul_dd, cmatmul_do, cmatmul_od @@ -55,7 +56,7 @@ export cdot, cmvmul, cmvmul_d, cvmmul, cvmmul_d, cmvmul_block export cmvmul_color, cmvmul_d_color, cvmmul_color, cvmmul_d_color export ckron, spintrace, cmvmul_spin_proj, spin_proj, σμν_spin_mul export _unwrap_val, SU, restore_last_col, restore_last_row, FLOAT_TYPE -export cinv, i32, spintrace_pauli +export cinv, i32, spintrace_pauli, lower_case abstract type AbstractIterator end struct Sequential <: AbstractIterator end @@ -64,6 +65,8 @@ struct Checkerboard4 <: AbstractIterator end struct EvenSites <: AbstractIterator end struct OddSites <: AbstractIterator end +lower_case(str) = Unicode.normalize(str; casefold=true) + @inline _unwrap_val(::Val{B}) where {B} = B @inline set_ext!(::Nothing, ::Integer) = nothing