JuliaMolSim / Molly.jl

Molecular simulation in Julia
Other
390 stars 53 forks source link

apply_coupling! method is not found for custom coupling function #137

Closed HLinde closed 1 year ago

HLinde commented 1 year ago

Hi, I tried implementing a custom coupling function analogue to the documentation but did not get it to work. The issue seems to be, that the apply_coupling method is not found, I get a "ERROR: LoadError: MethodError: no method matching apply_coupling!". Can you help me with that? Did I miss something there? Thanks!

Full error message:

ERROR: LoadError: MethodError: no method matching apply_coupling!(::System{3, false, Float64, Vector{Atom{Float64, Quantity{Float64, šŒ, Unit
ful.FreeUnits{(u,), šŒ, nothing}}, Quantity{Float64, š‹, Unitful.FreeUnits{(nm,), š‹, nothing}}, Quantity{Float64, š‹^2 šŒ š^-1 š“^-2, Unitful.Fre
eUnits{(kJ, mol^-1), š‹^2 šŒ š^-1 š“^-2, nothing}}}}, Vector{SVector{3, Quantity{Float64, š‹, Unitful.FreeUnits{(nm,), š‹, nothing}}}}, CubicBoun
dary{Quantity{Float64, š‹, Unitful.FreeUnits{(nm,), š‹, nothing}}}, Vector{SVector{3, Quantity{Float64, š‹ š“^-1, Unitful.FreeUnits{(nm, ps^-1),
 š‹ š“^-1, nothing}}}}, Vector{Any}, Nothing, Tuple{LennardJones{false, NoCutoff, Int64, Int64, Unitful.FreeUnits{(kJ, nm^-1, mol^-1), š‹ šŒ š^-
1 š“^-2, nothing}, Unitful.FreeUnits{(kJ, mol^-1), š‹^2 šŒ š^-1 š“^-2, nothing}}}, Tuple{}, Tuple{}, Tuple{}, NoNeighborFinder, NamedTuple{(:tem
p, :coords), Tuple{GeneralObservableLogger{Quantity{Float64, ššÆ, Unitful.FreeUnits{(K,), ššÆ, nothing}}, typeof(Molly.temperature_wrapper)}, Ge
neralObservableLogger{Vector{SVector{3, Quantity{Float64, š‹, Unitful.FreeUnits{(nm,), š‹, nothing}}}}, typeof(Molly.coordinates_wrapper)}}}, 
Quantity{Float64, š‹^2 šŒ ššÆ^-1 š“^-2, Unitful.FreeUnits{(kJ, K^-1), š‹^2 šŒ ššÆ^-1 š“^-2, nothing}}, Unitful.FreeUnits{(kJ, nm^-1, mol^-1), š‹ šŒ š^-1
 š“^-2, nothing}, Unitful.FreeUnits{(kJ, mol^-1), š‹^2 šŒ š^-1 š“^-2, nothing}, Vector{Quantity{Float64, šŒ, Unitful.FreeUnits{(u,), šŒ, nothing}}
}}, ::MyCoupler, ::VelocityVerlet{Quantity{Float64, š“, Unitful.FreeUnits{(ps,), š“, nothing}}, Tuple{AndersenThermostat{Quantity{Float64, ššÆ, 
Unitful.FreeUnits{(K,), ššÆ, nothing}}, Quantity{Float64, š“, Unitful.FreeUnits{(ps,), š“, nothing}}}, MonteCarloBarostat{Float64, Quantity{Floa
t64, šŒ š‹^-1 š“^-2, Unitful.FreeUnits{(bar,), šŒ š‹^-1 š“^-2, nothing}}, Quantity{Float64, ššÆ, Unitful.FreeUnits{(K,), ššÆ, nothing}}, Quantity{Floa
t64, š‹^3, Unitful.FreeUnits{(nm^3,), š‹^3, nothing}}}, MyCoupler}}, ::Nothing, ::Int64; n_threads::Int64)

Closest candidates are:
  apply_coupling!(::Any, ::Union{Tuple, NamedTuple}, ::Any, ::Any, ::Any; kwargs...)
   @ Molly ~/miniconda3/share/julia/packages/Molly/SRXWU/src/coupling.jl:23
  apply_coupling!(::Any, ::RescaleThermostat, ::Any, ::Any, ::Integer; n_threads)
   @ Molly ~/miniconda3/share/julia/packages/Molly/SRXWU/src/coupling.jl:100
  apply_coupling!(::Any, ::BerendsenThermostat, ::Any, ::Any, ::Integer; n_threads)
   @ Molly ~/miniconda3/share/julia/packages/Molly/SRXWU/src/coupling.jl:124
  ...

I tried to provide a minimal (not working) example from code blocks in the documentation:

using Molly

struct MyCoupler
    # Any properties, e.g. a target temperature or coupling constant
end

function apply_coupling!(sys, coupling::MyCoupler, sim, neighbors, step_n;
    n_threads=Threads.nthreads())
# Do something to the simulation, e.g. scale the velocities
# Return whether the coupling has invalidated the currently stored forces,
#   for example by changing the coordinates
recompute_forces = false
return recompute_forces
end
custom_coupler = MyCoupler()

n_atoms = 100
atom_mass = 10.0u"u"
atoms = [Atom(mass=atom_mass, Ļƒ=0.3u"nm", Ļµ=0.2u"kJ * mol^-1") for i in 1:n_atoms]
boundary = CubicBoundary(2.0u"nm") # Periodic boundary conditions with a 2 nm cube
coords = place_atoms(n_atoms, boundary; min_dist=0.3u"nm") # Random placement without clashing

temp = 100.0u"K"
velocities = [random_velocity(atom_mass, temp) for i in 1:n_atoms]

pairwise_inters = (LennardJones(),) # Don't forget the trailing comma!

sys = System(
    atoms=atoms,
    coords=coords,
    boundary=boundary,
    velocities=velocities,
    pairwise_inters=pairwise_inters,
)

simulator = VelocityVerlet(dt=0.001u"ps", coupling=custom_coupler)

simulate!(sys, simulator, 1_000)
jgreener64 commented 1 year ago

Ah it should be function Molly.apply_coupling!(sys, ...) since you are extending the method. I'll push a docs fix for this, thanks for spotting.

HLinde commented 1 year ago

Ah, that's easy to fix :D Thanks for the help! :)