From 49c22f99872ae3cf652ef08390dbbe9db7989313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20H=C3=B6ft?= Date: Fri, 20 Mar 2015 14:29:54 +0100 Subject: [PATCH 1/2] blocking_scheme: add function to determine next sampling step This internal function calculates the next sampling step in the blocking scheme. This may be used if any preparation for the correlation function is required before the actual sampling (e.g. to call enable_aux() before the force calculation) --- .../observables/dynamics/blocking_scheme.cpp | 30 ++++++++++++++++++- .../observables/dynamics/blocking_scheme.hpp | 2 ++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/halmd/observables/dynamics/blocking_scheme.cpp b/halmd/observables/dynamics/blocking_scheme.cpp index c08ee2496..9d6315e50 100644 --- a/halmd/observables/dynamics/blocking_scheme.cpp +++ b/halmd/observables/dynamics/blocking_scheme.cpp @@ -1,5 +1,7 @@ /* - * Copyright © 2011 Peter Colberg and Felix Höfling + * Copyright © 2011 Felix Höfling + * Copyright © 2015 Nicolas Höft + * Copyright © 2011 Peter Colberg * * This file is part of HALMD. * @@ -150,6 +152,31 @@ void blocking_scheme::sample() on_append_sample_(); } +blocking_scheme::step_type blocking_scheme::next() const +{ + LOG_TRACE("compute next occurance of a sampling step"); + step_type next_step; + step_type const step = clock_->step(); + + // TODO: is this sufficient? + next_step = step + separation_; + + // iterate over all coarse-graining levels + for (unsigned int i = 0; i < interval_.size(); ++i) { + // calculate the next occuring sampling measured from step + step_type next; + if (origin_[i] < step) { + next = origin_[i] + ((step - 1 - origin_[i]) / interval_[i] + 1) * interval_[i]; + } + else { + next = origin_[i]; + } + + next_step = min(next, next_step); + } + return next_step; +} + void blocking_scheme::finalise() { on_prepend_finalise_(); @@ -264,6 +291,7 @@ void blocking_scheme::luaopen(lua_State* L) .def("on_append_sample", &blocking_scheme::on_append_sample) .def("on_prepend_finalise", &blocking_scheme::on_prepend_finalise) .def("on_append_finalise", &blocking_scheme::on_append_finalise) + .def("next", &blocking_scheme::next) ] ] ]; diff --git a/halmd/observables/dynamics/blocking_scheme.hpp b/halmd/observables/dynamics/blocking_scheme.hpp index cd7eda548..c13a7d998 100644 --- a/halmd/observables/dynamics/blocking_scheme.hpp +++ b/halmd/observables/dynamics/blocking_scheme.hpp @@ -119,6 +119,8 @@ class blocking_scheme return time_; } + step_type next() const; + /** Lua bindings */ static void luaopen(lua_State* L); From 43398c74b6be7bf81ead0a2e511607c5ef810a29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20H=C3=B6ft?= Date: Fri, 20 Mar 2015 15:15:27 +0100 Subject: [PATCH 2/2] dynamics/blocking_scheme: call aux_enable() only if required Instead of letting the tcf call particle:aux_enable(), let the blocking scheme handle it, as it knows (through `next()') when a sampling step occurs. If the correlation module has, aux_enable defined, particle:aux_enable() will be called automatically then. This is a follow-up for 02ed3a22a9c and reverts it. Refs #282179 --- .../dynamics/blocking_scheme.lua.in | 17 +++++++------ .../observables/dynamics/correlation.lua.in | 18 +++++++++++++ .../stress_tensor_autocorrelation.lua.in | 25 ++----------------- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/lua/halmd/observables/dynamics/blocking_scheme.lua.in b/lua/halmd/observables/dynamics/blocking_scheme.lua.in index f8c355073..2ebb49945 100644 --- a/lua/halmd/observables/dynamics/blocking_scheme.lua.in +++ b/lua/halmd/observables/dynamics/blocking_scheme.lua.in @@ -1,5 +1,6 @@ -- -- Copyright © 2011-2014 Felix Höfling +-- Copyright © 2015 Nicolas Höft -- Copyright © 2011-2012 Peter Colberg -- -- This file is part of HALMD. @@ -123,13 +124,15 @@ local M = module(function(args) local conn = {} result.disconnect = utility.signal.disconnect(conn, "correlation function") - -- establish internal connections of the correlation function - -- e.g., particle:enable_aux() → sampler.on_prepare_force, - -- and append to our connection table - if tcf.connect then - conn_ = tcf:connect({every = every}) -- FIXME pass actual grid of sampling steps - for i,c in ipairs(conn_) do - table.insert(conn, c) + -- enable auxiliary variable calculation, if necessary for correlation function + if tcf.aux_enable then + local particles = utility.assert_type(tcf.aux_enable, "table") + for i,p in ipairs(particles) do + table.insert(conn, sampler:on_prepare(function() + if self:next() == clock.step then + p:aux_enable() + end + end, 1, clock.step)) end end diff --git a/lua/halmd/observables/dynamics/correlation.lua.in b/lua/halmd/observables/dynamics/correlation.lua.in index 30b768a7c..5f244834a 100644 --- a/lua/halmd/observables/dynamics/correlation.lua.in +++ b/lua/halmd/observables/dynamics/correlation.lua.in @@ -83,6 +83,7 @@ local blocking_scheme_adaptor = assert(libhalmd.observables.samples.blocking_sch -- :param args.location: default location within file -- :type args.location: string table -- :param string args.desc: module description +-- :param table args.aux_enable: sequence of :class:`halmd.mdsim.particle` instances *(optional)* -- -- The argument ``acquire`` is a callable or a table of up to 2 callables that -- yield the samples to be correlated. @@ -95,6 +96,13 @@ local blocking_scheme_adaptor = assert(libhalmd.observables.samples.blocking_sch -- H5MD files, it obeys the structure {``"dynamics"``, particle group, name of -- correlation function}. -- +-- The parameter ``aux_enable`` is useful if ``acquire()`` depends on one of +-- the auxiliary force variables, see :meth:`halmd.mdsim.particle.aux_enable` +-- for details. In sampling steps of the correlation function, each ``particle`` +-- instance listed in ``aux_enable`` is notified to update the auxiliary +-- variables before the sampling step. Thereby, redundant force calculations +-- can be avoided. +-- -- .. method:: acquire() -- -- Acquire sample(s). @@ -113,6 +121,11 @@ local blocking_scheme_adaptor = assert(libhalmd.observables.samples.blocking_sch -- -- Module description. -- +-- .. attribute:: aux_enable +-- +-- Sequence of particle instances that require auxiliary variables +-- during sampling. +-- -- .. class:: writer(args) -- -- Construct file writer. @@ -133,6 +146,7 @@ local M = module(function(args) local shape = utility.assert_type(args.shape or {}, "table") local location = utility.assert_type(utility.assert_kwarg(args, "location"), "table") local desc = utility.assert_type(utility.assert_kwarg(args, "desc"), "string") + local aux_enable = utility.assert_type(args.aux_enable or {}, "table") -- ensure that acquire is a table if not (type(acquire) == "table") then @@ -165,6 +179,10 @@ local M = module(function(args) return writer end end) + self.aux_enable = property(function(self) + return aux_enable + end) + return self end) diff --git a/lua/halmd/observables/dynamics/stress_tensor_autocorrelation.lua.in b/lua/halmd/observables/dynamics/stress_tensor_autocorrelation.lua.in index 54cb846a8..adfd97d4e 100644 --- a/lua/halmd/observables/dynamics/stress_tensor_autocorrelation.lua.in +++ b/lua/halmd/observables/dynamics/stress_tensor_autocorrelation.lua.in @@ -1,5 +1,5 @@ -- --- Copyright © 2013 Nicolas Höft +-- Copyright © 2013-2015 Nicolas Höft -- Copyright © 2013-2014 Felix Höfling -- -- This file is part of HALMD. @@ -82,19 +82,6 @@ local sampler = require("halmd.observables.sampler") -- -- Module description. -- --- .. method:: connect(args) --- --- :param table args: keyword arguments --- :param args.every: sampling interval --- :returns: sequence of signal connections --- --- *Internal use only.* This function is called upon registration by --- ``blocking_scheme:correlation()``. --- --- Connect ``msv.group.particle:aux_enable()`` to the signal --- ``on_prepend_force`` of :class:`halmd.observables.sampler` using the --- interval ``every``. --- -- .. class:: writer(args) -- -- Construct file writer. @@ -136,17 +123,9 @@ local M = module(function(args) , location = {"dynamics", label, "stress_tensor_autocorrelation"} -- module description , desc = ("stress tensor autocorrelation of %s particles"):format(label) + , aux_enable = {msv.group.particle} })) - self.connect = function(self, args) - local every = utility.assert_kwarg(args, "every") - - local conn = { - assert(sampler:on_prepare(function() msv.group.particle:aux_enable() end, every, clock.step)) - } - return conn - end - return self end)