From a8cfda16466b0ab97ab73aa5cc0fc2586e3dd2c9 Mon Sep 17 00:00:00 2001 From: Gareth Tribello <gareth.tribello@gmail.com> Date: Sun, 1 May 2016 11:53:17 +0100 Subject: [PATCH] Started adding all the stuff for reweighting in an averaging base class --- .../rt-histo/analysis.0.fesA1.reference | 2 +- regtest/analysis/rt-histo/fesA1.reference | 2 +- regtest/analysis/rt-histo/fesA1u.reference | 2 +- regtest/analysis/rt-histo/fesA2.reference | 2 +- regtest/analysis/rt-histo/fesA2u.reference | 2 +- regtest/analysis/rt-histo/fesA3.reference | 2 +- regtest/analysis/rt0/histoA.reference | 20 +-- regtest/analysis/rt0/histoB.reference | 28 ++-- regtest/analysis/rt0/histoD.reference | 4 +- regtest/analysis/rt0/histoD1.reference | 4 +- regtest/analysis/rt0/histoE.reference | 4 +- regtest/analysis/rt0/plumed.dat | 34 +++-- .../analysis.0.contour2.dat.reference | 2 +- .../rt-wcsurface2/contour2.dat.reference | 2 +- .../analysis.0.dens1b.reference | 2 +- .../rt-dens-average/dens1.reference | 2 +- .../rt-dens-average/dens1b.reference | 2 +- .../rt-dens-average/dens1ba.reference | 104 +++++++-------- .../rt-dens-average/dens2.reference | 2 +- .../rt-dens-average/dens5.reference | 2 +- .../rt-dens-average/dens5a.reference | 104 +++++++-------- .../rt-dens-average/interpol.reference | 2 +- .../multicolvar/rt-dens-average/plumed.dat | 20 ++- .../multicolvar/rt-dens/interpol.reference | 2 +- regtest/multicolvar/rt-dens/plumed.dat | 4 +- src/analysis/Histogram.cpp | 22 +-- src/bias/ReweightBase.cpp | 73 ++++++++++ src/bias/ReweightBase.h | 51 +++++++ src/bias/ReweightBias.cpp | 67 ++++++++++ src/bias/ReweightMetad.cpp | 67 ++++++++++ src/bias/ReweightTemperature.cpp | 78 +++++++++++ src/core/ActionWithArguments.h | 2 +- src/gridtools/ActionWithGrid.cpp | 88 ++---------- src/gridtools/ActionWithGrid.h | 33 +---- src/gridtools/ActionWithInputGrid.cpp | 17 ++- src/gridtools/ActionWithInputGrid.h | 6 +- src/gridtools/AverageOnGrid.cpp | 17 +-- src/gridtools/AverageOnGrid.h | 1 - src/gridtools/ContourFindingBase.cpp | 2 +- src/gridtools/ContourFindingBase.h | 2 +- src/gridtools/ConvertToFES.cpp | 5 +- src/gridtools/DumpCube.cpp | 42 +++--- src/gridtools/DumpGrid.cpp | 53 ++------ src/gridtools/FindContour.cpp | 12 +- src/gridtools/FindContourSurface.cpp | 22 +-- src/gridtools/FourierTransform.cpp | 6 +- src/gridtools/GridPrintingBase.cpp | 76 +++++++++++ src/gridtools/GridPrintingBase.h | 48 +++++++ src/gridtools/GridVessel.cpp | 46 ++----- src/gridtools/GridVessel.h | 45 +------ src/gridtools/HistogramOnGrid.cpp | 13 +- src/gridtools/HistogramOnGrid.h | 2 +- src/gridtools/InterpolateGrid.cpp | 17 +-- src/multicolvar/MultiColvarDensity.cpp | 16 +-- src/vesselbase/ActionWithAveraging.cpp | 126 ++++++++++++++++++ src/vesselbase/ActionWithAveraging.h | 94 +++++++++++++ src/vesselbase/ActionWithVessel.cpp | 2 - src/vesselbase/AveragingVessel.cpp | 62 +++++++++ src/vesselbase/AveragingVessel.h | 101 ++++++++++++++ 59 files changed, 1157 insertions(+), 513 deletions(-) create mode 100644 src/bias/ReweightBase.cpp create mode 100644 src/bias/ReweightBase.h create mode 100644 src/bias/ReweightBias.cpp create mode 100644 src/bias/ReweightMetad.cpp create mode 100644 src/bias/ReweightTemperature.cpp create mode 100644 src/gridtools/GridPrintingBase.cpp create mode 100644 src/gridtools/GridPrintingBase.h create mode 100644 src/vesselbase/ActionWithAveraging.cpp create mode 100644 src/vesselbase/ActionWithAveraging.h create mode 100644 src/vesselbase/AveragingVessel.cpp create mode 100644 src/vesselbase/AveragingVessel.h diff --git a/regtest/analysis/rt-histo/analysis.0.fesA1.reference b/regtest/analysis/rt-histo/analysis.0.fesA1.reference index 238a9b202..ba54f4733 100644 --- a/regtest/analysis/rt-histo/analysis.0.fesA1.reference +++ b/regtest/analysis/rt-histo/analysis.0.fesA1.reference @@ -1,5 +1,5 @@ #! FIELDS x fA1 dfA1_x -#! SET normalisation 0.0000 +#! SET normalisation 1.0000 #! SET min_x 0.0 #! SET max_x 3.0 #! SET nbins_x 100 diff --git a/regtest/analysis/rt-histo/fesA1.reference b/regtest/analysis/rt-histo/fesA1.reference index 6edf125bb..5b9a304f3 100644 --- a/regtest/analysis/rt-histo/fesA1.reference +++ b/regtest/analysis/rt-histo/fesA1.reference @@ -1,5 +1,5 @@ #! FIELDS x fA1 dfA1_x -#! SET normalisation 0.0000 +#! SET normalisation 1.0000 #! SET min_x 0.0 #! SET max_x 3.0 #! SET nbins_x 100 diff --git a/regtest/analysis/rt-histo/fesA1u.reference b/regtest/analysis/rt-histo/fesA1u.reference index c15e81f17..674191daf 100644 --- a/regtest/analysis/rt-histo/fesA1u.reference +++ b/regtest/analysis/rt-histo/fesA1u.reference @@ -1,5 +1,5 @@ #! FIELDS x fA1u dfA1u_x -#! SET normalisation 0.0000 +#! SET normalisation 1.0000 #! SET min_x 0.0 #! SET max_x 3.0 #! SET nbins_x 100 diff --git a/regtest/analysis/rt-histo/fesA2.reference b/regtest/analysis/rt-histo/fesA2.reference index 6edf125bb..5b9a304f3 100644 --- a/regtest/analysis/rt-histo/fesA2.reference +++ b/regtest/analysis/rt-histo/fesA2.reference @@ -1,5 +1,5 @@ #! FIELDS x fA1 dfA1_x -#! SET normalisation 0.0000 +#! SET normalisation 1.0000 #! SET min_x 0.0 #! SET max_x 3.0 #! SET nbins_x 100 diff --git a/regtest/analysis/rt-histo/fesA2u.reference b/regtest/analysis/rt-histo/fesA2u.reference index c15e81f17..674191daf 100644 --- a/regtest/analysis/rt-histo/fesA2u.reference +++ b/regtest/analysis/rt-histo/fesA2u.reference @@ -1,5 +1,5 @@ #! FIELDS x fA1u dfA1u_x -#! SET normalisation 0.0000 +#! SET normalisation 1.0000 #! SET min_x 0.0 #! SET max_x 3.0 #! SET nbins_x 100 diff --git a/regtest/analysis/rt-histo/fesA3.reference b/regtest/analysis/rt-histo/fesA3.reference index 6edf125bb..5b9a304f3 100644 --- a/regtest/analysis/rt-histo/fesA3.reference +++ b/regtest/analysis/rt-histo/fesA3.reference @@ -1,5 +1,5 @@ #! FIELDS x fA1 dfA1_x -#! SET normalisation 0.0000 +#! SET normalisation 1.0000 #! SET min_x 0.0 #! SET max_x 3.0 #! SET nbins_x 100 diff --git a/regtest/analysis/rt0/histoA.reference b/regtest/analysis/rt0/histoA.reference index a9c66815b..da854d9bc 100644 --- a/regtest/analysis/rt0/histoA.reference +++ b/regtest/analysis/rt0/histoA.reference @@ -44,28 +44,28 @@ 1.1100 0.0000 0.0000 1.1400 0.0031 0.1101 1.1700 0.0086 0.2842 - 1.2000 0.0221 0.6648 + 1.2000 0.0222 0.6648 1.2300 0.0521 1.4068 - 1.2600 0.1119 2.6873 + 1.2600 0.1120 2.6873 1.2900 0.2199 4.6183 - 1.3200 0.3947 7.1055 + 1.3200 0.3948 7.1055 1.3500 0.6476 9.7138 - 1.3800 0.9709 11.6511 - 1.4100 1.3304 11.9739 - 1.4400 1.6661 9.9968 + 1.3800 0.9709 11.6512 + 1.4100 1.3304 11.9738 + 1.4400 1.6661 9.9967 1.4700 1.9069 5.7208 1.5000 1.9947 0.0000 1.5300 1.9069 -5.7208 - 1.5600 1.6661 -9.9968 - 1.5900 1.3304 -11.9739 + 1.5600 1.6661 -9.9967 + 1.5900 1.3304 -11.9738 1.6200 0.9724 -11.5957 1.6500 0.6520 -9.5611 - 1.6800 0.4067 -6.7240 + 1.6800 0.4067 -6.7241 1.7100 0.2497 -3.7552 1.7400 0.1799 -0.9216 1.7700 0.1937 1.8508 1.8000 0.2921 4.7343 - 1.8300 0.4788 7.7100 + 1.8300 0.4789 7.7099 1.8600 0.7517 10.3708 1.8900 1.0893 11.9819 1.9200 1.4485 11.5877 diff --git a/regtest/analysis/rt0/histoB.reference b/regtest/analysis/rt0/histoB.reference index 5760efcba..7b569d51f 100644 --- a/regtest/analysis/rt0/histoB.reference +++ b/regtest/analysis/rt0/histoB.reference @@ -1,5 +1,5 @@ #! FIELDS x hB dhB_x -#! SET normalisation 2.2220 +#! SET normalisation 4.0542 #! SET min_x 0.0 #! SET max_x 3.0 #! SET nbins_x 100 @@ -42,37 +42,37 @@ 1.0500 0.0000 0.0000 1.0800 0.0000 0.0000 1.1100 0.0000 0.0000 - 1.1400 0.0027 0.0991 - 1.1700 0.0077 0.2558 + 1.1400 0.0028 0.0991 + 1.1700 0.0078 0.2558 1.2000 0.0199 0.5984 1.2300 0.0469 1.2663 1.2600 0.1008 2.4189 - 1.2900 0.1979 4.1570 + 1.2900 0.1979 4.1569 1.3200 0.3553 6.3957 1.3500 0.5829 8.7435 - 1.3800 0.8740 10.4873 + 1.3800 0.8739 10.4873 1.4100 1.1975 10.7777 1.4400 1.4997 8.9981 - 1.4700 1.7165 5.1493 - 1.5000 1.7954 0.0000 - 1.5300 1.7165 -5.1493 + 1.4700 1.7164 5.1493 + 1.5000 1.7955 0.0000 + 1.5300 1.7164 -5.1493 1.5600 1.4997 -8.9981 1.5900 1.1975 -10.7777 - 1.6200 0.8756 -10.4263 + 1.6200 0.8755 -10.4263 1.6500 0.5877 -8.5755 1.6800 0.3684 -5.9762 1.7100 0.2307 -3.2076 1.7400 0.1755 -0.4767 1.7700 0.2027 2.3167 - 1.8000 0.3169 5.3400 + 1.8000 0.3169 5.3401 1.8300 0.5250 8.5369 - 1.8600 0.8262 11.4287 + 1.8600 0.8262 11.4288 1.8900 1.1981 13.1788 1.9200 1.5931 12.7452 - 1.9500 1.9362 9.6808 - 1.9800 2.1505 4.3010 + 1.9500 1.9362 9.6809 + 1.9800 2.1505 4.3011 2.0100 2.1830 -2.1830 - 2.0400 2.0253 -8.1011 + 2.0400 2.0253 -8.1012 2.0700 1.7172 -12.0206 2.1000 1.3307 -13.3071 2.1300 0.9424 -12.2517 diff --git a/regtest/analysis/rt0/histoD.reference b/regtest/analysis/rt0/histoD.reference index c2827416c..a05fbfe36 100644 --- a/regtest/analysis/rt0/histoD.reference +++ b/regtest/analysis/rt0/histoD.reference @@ -1,5 +1,5 @@ #! FIELDS x hD -#! SET normalisation 5.5474 +#! SET normalisation 4.0542 #! SET min_x 0.0 #! SET max_x 3.0 #! SET nbins_x 100 @@ -37,7 +37,7 @@ 0.9000 0.0000 0.9300 0.0000 0.9600 0.0000 - 0.9900 1.4932 + 0.9900 0.0000 1.0200 0.0000 1.0500 0.0000 1.0800 0.0000 diff --git a/regtest/analysis/rt0/histoD1.reference b/regtest/analysis/rt0/histoD1.reference index 7a6242f4e..10fd0663e 100644 --- a/regtest/analysis/rt0/histoD1.reference +++ b/regtest/analysis/rt0/histoD1.reference @@ -1,5 +1,5 @@ #! FIELDS x hD1 -#! SET normalisation 1.4932 +#! SET normalisation 0.0000 #! SET min_x 0.0 #! SET max_x 3.0 #! SET nbins_x 100 @@ -37,7 +37,7 @@ 0.9000 0.0000 0.9300 0.0000 0.9600 0.0000 - 0.9900 1.4932 + 0.9900 0.0000 1.0200 0.0000 1.0500 0.0000 1.0800 0.0000 diff --git a/regtest/analysis/rt0/histoE.reference b/regtest/analysis/rt0/histoE.reference index b36b2558f..1f18687de 100644 --- a/regtest/analysis/rt0/histoE.reference +++ b/regtest/analysis/rt0/histoE.reference @@ -1,5 +1,5 @@ #! FIELDS x fE -#! SET normalisation 3.0547 +#! SET normalisation 1.0000 #! SET min_x 0.0 #! SET max_x 3.0 #! SET nbins_x 100 @@ -37,7 +37,7 @@ 0.9000 inf 0.9300 inf 0.9600 inf - 0.9900 -1.0000 + 0.9900 inf 1.0200 inf 1.0500 inf 1.0800 inf diff --git a/regtest/analysis/rt0/plumed.dat b/regtest/analysis/rt0/plumed.dat index b5ff3b6cd..db0eeb44f 100755 --- a/regtest/analysis/rt0/plumed.dat +++ b/regtest/analysis/rt0/plumed.dat @@ -4,7 +4,6 @@ RESTRAINT ARG=x SLOPE=1.0 AT=0.0 HISTOGRAM ... ARG=x - TEMP=300 GRID_MIN=0.0 GRID_MAX=3.0 GRID_BIN=100 @@ -12,20 +11,21 @@ HISTOGRAM ... LABEL=hA ... HISTOGRAM -PRINT_GRID GRID=hA FILE=histoA STRIDE=1 FMT=%8.4f +DUMPGRID GRID=hA FILE=histoA STRIDE=1 FMT=%8.4f + +bias: REWEIGHT_BIAS TEMP=300 HISTOGRAM ... ARG=x - TEMP=300 GRID_MIN=0.0 GRID_MAX=3.0 GRID_BIN=100 BANDWIDTH=0.1 - REWEIGHT_BIAS + LOGWEIGHTS=bias LABEL=hB ... HISTOGRAM -PRINT_GRID GRID=hB FILE=histoB STRIDE=1 FMT=%8.4f +DUMPGRID GRID=hB FILE=histoB STRIDE=1 FMT=%8.4f HISTOGRAM ... ARG=x @@ -36,68 +36,66 @@ HISTOGRAM ... LABEL=hC ... HISTOGRAM -PRINT_GRID GRID=hC FILE=histoC USE_ALL_DATA +DUMPGRID GRID=hC FILE=histoC HISTOGRAM ... ARG=x - TEMP=300 GRID_MIN=0.0 GRID_MAX=3.0 GRID_BIN=100 KERNEL=DISCRETE - REWEIGHT_BIAS + LOGWEIGHTS=bias UNORMALIZED LABEL=hD ... HISTOGRAM -PRINT_GRID GRID=hD FILE=histoD FMT=%8.4f USE_ALL_DATA +DUMPGRID GRID=hD FILE=histoD FMT=%8.4f + +bias-ht: REWEIGHT_BIAS TEMP=10000 HISTOGRAM ... ARG=x - TEMP=10000 GRID_MIN=0.0 GRID_MAX=3.0 GRID_BIN=100 KERNEL=DISCRETE - REWEIGHT_BIAS + LOGWEIGHTS=bias-ht UNORMALIZED LABEL=hE ... HISTOGRAM fE: CONVERT_TO_FES GRID=hE TEMP=10000 -PRINT_GRID GRID=fE FMT=%8.4f USE_ALL_DATA FILE=histoE +DUMPGRID GRID=fE FMT=%8.4f FILE=histoE HISTOGRAM ... ARG=x - TEMP=300 GRID_MIN=0.0 GRID_MAX=3.0 GRID_BIN=100 KERNEL=DISCRETE - REWEIGHT_BIAS + LOGWEIGHTS=bias UPDATE_FROM=0 UPDATE_UNTIL=1 UNORMALIZED LABEL=hD1 ... HISTOGRAM -PRINT_GRID GRID=hD1 FILE=histoD1 FMT=%8.4f USE_ALL_DATA +DUMPGRID GRID=hD1 FILE=histoD1 FMT=%8.4f HISTOGRAM ... ARG=x - TEMP=300 GRID_MIN=0.0 GRID_MAX=3.0 GRID_BIN=100 KERNEL=DISCRETE - REWEIGHT_BIAS + LOGWEIGHTS=bias UPDATE_FROM=1 UPDATE_UNTIL=2 UNORMALIZED LABEL=hD2 ... HISTOGRAM -PRINT_GRID GRID=hD2 FILE=histoD2 FMT=%8.4f USE_ALL_DATA +DUMPGRID GRID=hD2 FILE=histoD2 FMT=%8.4f diff --git a/regtest/crystallization/rt-wcsurface2/analysis.0.contour2.dat.reference b/regtest/crystallization/rt-wcsurface2/analysis.0.contour2.dat.reference index bdc34b0f0..624036870 100644 --- a/regtest/crystallization/rt-wcsurface2/analysis.0.contour2.dat.reference +++ b/regtest/crystallization/rt-wcsurface2/analysis.0.contour2.dat.reference @@ -1,5 +1,5 @@ #! FIELDS x y ss2 -#! SET normalisation 0.0000 +#! SET normalisation 1.0000 #! SET min_x -7.27971 #! SET max_x 7.27971 #! SET nbins_x 14 diff --git a/regtest/crystallization/rt-wcsurface2/contour2.dat.reference b/regtest/crystallization/rt-wcsurface2/contour2.dat.reference index bdc34b0f0..624036870 100644 --- a/regtest/crystallization/rt-wcsurface2/contour2.dat.reference +++ b/regtest/crystallization/rt-wcsurface2/contour2.dat.reference @@ -1,5 +1,5 @@ #! FIELDS x y ss2 -#! SET normalisation 0.0000 +#! SET normalisation 1.0000 #! SET min_x -7.27971 #! SET max_x 7.27971 #! SET nbins_x 14 diff --git a/regtest/multicolvar/rt-dens-average/analysis.0.dens1b.reference b/regtest/multicolvar/rt-dens-average/analysis.0.dens1b.reference index 7a16efe95..f1a1ba1c4 100644 --- a/regtest/multicolvar/rt-dens-average/analysis.0.dens1b.reference +++ b/regtest/multicolvar/rt-dens-average/analysis.0.dens1b.reference @@ -1,5 +1,5 @@ #! FIELDS x dens.dens ddens.dens_x density ddensity_x -#! SET normalisation 0.0000 +#! SET normalisation 1.0000 #! SET min_x -2.5 #! SET max_x 2.5 #! SET nbins_x 50 diff --git a/regtest/multicolvar/rt-dens-average/dens1.reference b/regtest/multicolvar/rt-dens-average/dens1.reference index 147b4e1b3..0f0bb8187 100644 --- a/regtest/multicolvar/rt-dens-average/dens1.reference +++ b/regtest/multicolvar/rt-dens-average/dens1.reference @@ -1,5 +1,5 @@ #! FIELDS x dens.dens ddens.dens_x density ddensity_x -#! SET normalisation 0.0000 +#! SET normalisation 2.0000 #! SET min_x -2.5 #! SET max_x 2.5 #! SET nbins_x 50 diff --git a/regtest/multicolvar/rt-dens-average/dens1b.reference b/regtest/multicolvar/rt-dens-average/dens1b.reference index 9fb24891b..074db3f29 100644 --- a/regtest/multicolvar/rt-dens-average/dens1b.reference +++ b/regtest/multicolvar/rt-dens-average/dens1b.reference @@ -1,5 +1,5 @@ #! FIELDS x dens.dens ddens.dens_x density ddensity_x -#! SET normalisation 0.0000 +#! SET normalisation 1.0000 #! SET min_x -2.5 #! SET max_x 2.5 #! SET nbins_x 50 diff --git a/regtest/multicolvar/rt-dens-average/dens1ba.reference b/regtest/multicolvar/rt-dens-average/dens1ba.reference index a92621e9d..d60f11274 100644 --- a/regtest/multicolvar/rt-dens-average/dens1ba.reference +++ b/regtest/multicolvar/rt-dens-average/dens1ba.reference @@ -1,56 +1,56 @@ -#! FIELDS x dens.dens ddens.dens_x -#! SET normalisation 0.0000 +#! FIELDS x dens.dens ddens.dens_x density ddensity_x +#! SET normalisation 1.0000 #! SET min_x -2.5 #! SET max_x 2.5 #! SET nbins_x 50 #! SET periodic_x true - -2.5000 1.0000 0.0000 - -2.4000 1.0000 0.0000 - -2.3000 1.0000 0.0000 - -2.2000 1.0000 0.0000 - -2.1000 0.0000 0.0000 - -2.0000 0.0000 0.0000 - -1.9000 0.0000 0.0000 - -1.8000 0.0000 0.0000 - -1.7000 0.0000 0.0000 - -1.6000 0.0000 0.0000 - -1.5000 0.0000 0.0000 - -1.4000 0.0000 0.0000 - -1.3000 0.0000 0.0000 - -1.2000 0.0000 0.0000 - -1.1000 0.0000 0.0000 - -1.0000 0.0000 0.0000 - -0.9000 0.0000 0.0000 - -0.8000 0.0000 0.0000 - -0.7000 0.0000 0.0000 - -0.6000 0.0000 0.0000 - -0.5000 0.0000 0.0000 - -0.4000 0.0000 0.0000 - -0.3000 0.0000 0.0000 - -0.2000 0.0000 0.0000 - -0.1000 0.0000 0.0000 - 0.0000 0.0000 0.0000 - 0.1000 0.0000 0.0000 - 0.2000 0.0000 0.0000 - 0.3000 0.0000 0.0000 - 0.4000 0.0000 0.0000 - 0.5000 0.0000 0.0000 - 0.6000 0.0000 0.0000 - 0.7000 0.0000 0.0000 - 0.8000 0.0000 0.0000 - 0.9000 0.0000 0.0000 - 1.0000 0.0000 0.0000 - 1.1000 0.0000 0.0000 - 1.2000 1.0000 0.0000 - 1.3000 1.0000 0.0000 - 1.4000 1.0000 0.0000 - 1.5000 1.0000 -0.0000 - 1.6000 1.0000 0.0000 - 1.7000 1.0000 0.0000 - 1.8000 1.0000 0.0000 - 1.9000 1.0000 0.0000 - 2.0000 1.0000 0.0000 - 2.1000 1.0000 0.0000 - 2.2000 1.0000 -0.0000 - 2.3000 1.0000 0.0000 - 2.4000 1.0000 -0.0000 + -2.5000 1.0000 0.0000 0.0876 -1.0955 + -2.4000 1.0000 0.0000 0.0222 -0.3324 + -2.3000 1.0000 0.0000 0.0044 -0.0764 + -2.2000 1.0000 0.0000 0.0007 -0.0134 + -2.1000 0.0000 0.0000 0.0000 0.0000 + -2.0000 0.0000 0.0000 0.0000 0.0000 + -1.9000 0.0000 0.0000 0.0000 0.0000 + -1.8000 0.0000 0.0000 0.0000 0.0000 + -1.7000 0.0000 0.0000 0.0000 0.0000 + -1.6000 0.0000 0.0000 0.0000 0.0000 + -1.5000 0.0000 0.0000 0.0000 0.0000 + -1.4000 0.0000 0.0000 0.0000 0.0000 + -1.3000 0.0000 0.0000 0.0000 0.0000 + -1.2000 0.0000 0.0000 0.0000 0.0000 + -1.1000 0.0000 0.0000 0.0000 0.0000 + -1.0000 0.0000 0.0000 0.0000 0.0000 + -0.9000 0.0000 0.0000 0.0000 0.0000 + -0.8000 0.0000 0.0000 0.0000 0.0000 + -0.7000 0.0000 0.0000 0.0000 0.0000 + -0.6000 0.0000 0.0000 0.0000 0.0000 + -0.5000 0.0000 0.0000 0.0000 0.0000 + -0.4000 0.0000 0.0000 0.0000 0.0000 + -0.3000 0.0000 0.0000 0.0000 0.0000 + -0.2000 0.0000 0.0000 0.0000 0.0000 + -0.1000 0.0000 0.0000 0.0000 0.0000 + 0.0000 0.0000 0.0000 0.0000 0.0000 + 0.1000 0.0000 0.0000 0.0000 0.0000 + 0.2000 0.0000 0.0000 0.0000 0.0000 + 0.3000 0.0000 0.0000 0.0000 0.0000 + 0.4000 0.0000 0.0000 0.0000 0.0000 + 0.5000 0.0000 0.0000 0.0000 0.0000 + 0.6000 0.0000 0.0000 0.0000 0.0000 + 0.7000 0.0000 0.0000 0.0000 0.0000 + 0.8000 0.0000 0.0000 0.0000 0.0000 + 0.9000 0.0000 0.0000 0.0000 0.0000 + 1.0000 0.0000 0.0000 0.0000 0.0000 + 1.1000 0.0000 0.0000 0.0000 0.0000 + 1.2000 1.0000 0.0000 0.0007 0.0134 + 1.3000 1.0000 0.0000 0.0044 0.0764 + 1.4000 1.0000 0.0000 0.0222 0.3324 + 1.5000 1.0000 -0.0000 0.0876 1.0955 + 1.6000 1.0000 0.0000 0.2700 2.6995 + 1.7000 1.0000 0.0000 0.6476 4.8569 + 1.8000 1.0000 0.0000 1.2099 6.0493 + 1.9000 1.0000 0.0000 1.7603 4.4008 + 2.0000 1.0000 0.0000 1.9947 0.0000 + 2.1000 1.0000 0.0000 1.7603 -4.4008 + 2.2000 1.0000 -0.0000 1.2099 -6.0493 + 2.3000 1.0000 0.0000 0.6476 -4.8569 + 2.4000 1.0000 -0.0000 0.2700 -2.6995 diff --git a/regtest/multicolvar/rt-dens-average/dens2.reference b/regtest/multicolvar/rt-dens-average/dens2.reference index 147b4e1b3..0f0bb8187 100644 --- a/regtest/multicolvar/rt-dens-average/dens2.reference +++ b/regtest/multicolvar/rt-dens-average/dens2.reference @@ -1,5 +1,5 @@ #! FIELDS x dens.dens ddens.dens_x density ddensity_x -#! SET normalisation 0.0000 +#! SET normalisation 2.0000 #! SET min_x -2.5 #! SET max_x 2.5 #! SET nbins_x 50 diff --git a/regtest/multicolvar/rt-dens-average/dens5.reference b/regtest/multicolvar/rt-dens-average/dens5.reference index 147b4e1b3..0f0bb8187 100644 --- a/regtest/multicolvar/rt-dens-average/dens5.reference +++ b/regtest/multicolvar/rt-dens-average/dens5.reference @@ -1,5 +1,5 @@ #! FIELDS x dens.dens ddens.dens_x density ddensity_x -#! SET normalisation 0.0000 +#! SET normalisation 2.0000 #! SET min_x -2.5 #! SET max_x 2.5 #! SET nbins_x 50 diff --git a/regtest/multicolvar/rt-dens-average/dens5a.reference b/regtest/multicolvar/rt-dens-average/dens5a.reference index 5cd1d702e..a34c68c87 100644 --- a/regtest/multicolvar/rt-dens-average/dens5a.reference +++ b/regtest/multicolvar/rt-dens-average/dens5a.reference @@ -1,56 +1,56 @@ -#! FIELDS x dens.dens ddens.dens_x -#! SET normalisation 0.0000 +#! FIELDS x dens.dens ddens.dens_x density ddensity_x +#! SET normalisation 2.0000 #! SET min_x -2.5 #! SET max_x 2.5 #! SET nbins_x 50 #! SET periodic_x true - -2.5000 1.0000 0.0000 - -2.4000 1.0000 0.0000 - -2.3000 1.0000 0.0000 - -2.2000 1.0000 0.0000 - -2.1000 0.0000 0.0000 - -2.0000 0.0000 0.0000 - -1.9000 0.0000 0.0000 - -1.8000 0.0000 0.0000 - -1.7000 0.0000 0.0000 - -1.6000 0.0000 0.0000 - -1.5000 0.0000 0.0000 - -1.4000 0.0000 0.0000 - -1.3000 0.0000 0.0000 - -1.2000 0.0000 0.0000 - -1.1000 0.0000 0.0000 - -1.0000 0.0000 0.0000 - -0.9000 0.0000 0.0000 - -0.8000 0.0000 0.0000 - -0.7000 0.0000 0.0000 - -0.6000 0.0000 0.0000 - -0.5000 0.0000 0.0000 - -0.4000 0.0000 0.0000 - -0.3000 0.0000 0.0000 - -0.2000 0.0000 0.0000 - -0.1000 0.0000 0.0000 - 0.0000 0.0000 0.0000 - 0.1000 0.0000 0.0000 - 0.2000 2.0000 -0.0000 - 0.3000 2.0000 0.0000 - 0.4000 2.0000 0.0000 - 0.5000 2.0000 -0.0000 - 0.6000 2.0000 0.0000 - 0.7000 2.0000 0.0000 - 0.8000 2.0000 0.0000 - 0.9000 2.0000 -0.0000 - 1.0000 2.0000 0.0000 - 1.1000 2.0000 0.0000 - 1.2000 1.9994 -0.0138 - 1.3000 1.9933 -0.1662 - 1.4000 1.9241 -1.7526 - 1.5000 1.5000 -6.2500 - 1.6000 1.0759 -1.7526 - 1.7000 1.0067 -0.1662 - 1.8000 1.0006 -0.0138 - 1.9000 1.0000 0.0000 - 2.0000 1.0000 0.0000 - 2.1000 1.0000 0.0000 - 2.2000 1.0000 -0.0000 - 2.3000 1.0000 0.0000 - 2.4000 1.0000 -0.0000 + -2.5000 1.0000 0.0000 0.0438 -0.5478 + -2.4000 1.0000 0.0000 0.0111 -0.1662 + -2.3000 1.0000 0.0000 0.0022 -0.0382 + -2.2000 1.0000 0.0000 0.0003 -0.0067 + -2.1000 0.0000 0.0000 0.0000 0.0000 + -2.0000 0.0000 0.0000 0.0000 0.0000 + -1.9000 0.0000 0.0000 0.0000 0.0000 + -1.8000 0.0000 0.0000 0.0000 0.0000 + -1.7000 0.0000 0.0000 0.0000 0.0000 + -1.6000 0.0000 0.0000 0.0000 0.0000 + -1.5000 0.0000 0.0000 0.0000 0.0000 + -1.4000 0.0000 0.0000 0.0000 0.0000 + -1.3000 0.0000 0.0000 0.0000 0.0000 + -1.2000 0.0000 0.0000 0.0000 0.0000 + -1.1000 0.0000 0.0000 0.0000 0.0000 + -1.0000 0.0000 0.0000 0.0000 0.0000 + -0.9000 0.0000 0.0000 0.0000 0.0000 + -0.8000 0.0000 0.0000 0.0000 0.0000 + -0.7000 0.0000 0.0000 0.0000 0.0000 + -0.6000 0.0000 0.0000 0.0000 0.0000 + -0.5000 0.0000 0.0000 0.0000 0.0000 + -0.4000 0.0000 0.0000 0.0000 0.0000 + -0.3000 0.0000 0.0000 0.0000 0.0000 + -0.2000 0.0000 0.0000 0.0000 0.0000 + -0.1000 0.0000 0.0000 0.0000 0.0000 + 0.0000 0.0000 0.0000 0.0000 0.0000 + 0.1000 0.0000 0.0000 0.0000 0.0000 + 0.2000 2.0000 -0.0000 0.0003 0.0067 + 0.3000 2.0000 0.0000 0.0022 0.0382 + 0.4000 2.0000 0.0000 0.0111 0.1662 + 0.5000 2.0000 -0.0000 0.0438 0.5478 + 0.6000 2.0000 0.0000 0.1350 1.3498 + 0.7000 2.0000 0.0000 0.3238 2.4285 + 0.8000 2.0000 0.0000 0.6049 3.0246 + 0.9000 2.0000 -0.0000 0.8802 2.2004 + 1.0000 2.0000 0.0000 0.9974 0.0000 + 1.1000 2.0000 0.0000 0.8802 -2.2004 + 1.2000 1.9994 -0.0138 0.6053 -3.0179 + 1.3000 1.9933 -0.1662 0.3260 -2.3903 + 1.4000 1.9241 -1.7526 0.1461 -1.1836 + 1.5000 1.5000 -6.2500 0.0876 -0.0000 + 1.6000 1.0759 -1.7526 0.1461 1.1836 + 1.7000 1.0067 -0.1662 0.3260 2.3903 + 1.8000 1.0006 -0.0138 0.6053 3.0179 + 1.9000 1.0000 0.0000 0.8802 2.2004 + 2.0000 1.0000 0.0000 0.9974 0.0000 + 2.1000 1.0000 0.0000 0.8802 -2.2004 + 2.2000 1.0000 -0.0000 0.6049 -3.0246 + 2.3000 1.0000 0.0000 0.3238 -2.4285 + 2.4000 1.0000 -0.0000 0.1350 -1.3498 diff --git a/regtest/multicolvar/rt-dens-average/interpol.reference b/regtest/multicolvar/rt-dens-average/interpol.reference index 75d4ea449..3ff0707ad 100644 --- a/regtest/multicolvar/rt-dens-average/interpol.reference +++ b/regtest/multicolvar/rt-dens-average/interpol.reference @@ -1,5 +1,5 @@ #! FIELDS x interpol dinterpol_x -#! SET normalisation 0.0000 +#! SET normalisation 1.0000 #! SET min_x -2.5 #! SET max_x 2.5 #! SET nbins_x 100 diff --git a/regtest/multicolvar/rt-dens-average/plumed.dat b/regtest/multicolvar/rt-dens-average/plumed.dat index 371be5092..30bba5a3c 100644 --- a/regtest/multicolvar/rt-dens-average/plumed.dat +++ b/regtest/multicolvar/rt-dens-average/plumed.dat @@ -3,22 +3,28 @@ UNITS NATURAL dens: COORDINATIONNUMBER SPECIESA=2 SPECIESB=3-5 SWITCH={RATIONAL D_0=1.1 R_0=0.001 D_MAX=2.0} # Print the average (whole trajectory) density with a stride of one -dens1: MULTICOLVARDENS DATA=dens ORIGIN=1 DIR=x NBINS=50 BANDWIDTH=0.2 +dens1: MULTICOLVARDENS DATA=dens ORIGIN=1 DIR=x NBINS=50 UNORMALIZED BANDWIDTH=0.2 DUMPGRID GRID=dens1 STRIDE=1 FILE=dens1 FMT=%8.4f # Print the average density with a stride of two DUMPGRID GRID=dens1 STRIDE=2 FILE=dens2 FMT=%8.4f # Print the average density (whole trajectory) DUMPGRID GRID=dens1 FILE=dens5 FMT=%8.4f -DUMPGRID GRID=dens1 FILE=dens5a PRINT_AVERAGE FMT=%8.4f -# Print block averages (over two frames) of the density -dens1b: MULTICOLVARDENS DATA=dens ORIGIN=1 DIR=x NBINS=50 CLEAR=1 BANDWIDTH=0.2 +# Print the average (whole trajectory) density with a stride of one +dens1a: MULTICOLVARDENS DATA=dens ORIGIN=1 DIR=x NBINS=50 BANDWIDTH=0.2 +DUMPGRID GRID=dens1a FILE=dens5a FMT=%8.4f + +# Print unormalized averages (over two frames) of the density +dens1b: MULTICOLVARDENS DATA=dens ORIGIN=1 DIR=x NBINS=50 CLEAR=1 UNORMALIZED BANDWIDTH=0.2 DUMPGRID GRID=dens1b STRIDE=1 FILE=dens1b FMT=%8.4f -DUMPGRID GRID=dens1b STRIDE=1 FILE=dens1ba PRINT_AVERAGE FMT=%8.4f + +# Print block averages (over two frames) of the density +dens1ba: MULTICOLVARDENS DATA=dens ORIGIN=1 DIR=x NBINS=50 CLEAR=1 BANDWIDTH=0.2 +DUMPGRID GRID=dens1ba STRIDE=1 FILE=dens1ba FMT=%8.4f # Interpolate onto a finer grid and test fine: MULTICOLVARDENS DATA=dens ORIGIN=1 DIR=x NBINS=100 BANDWIDTH=0.1 -interpol: INTERPOLATE_GRID GRID=dens1 GRID_BIN=100 +interpol: INTERPOLATE_GRID GRID=dens1a STRIDE=2 GRID_BIN=100 -DUMPGRID GRID=fine FILE=fine_grid PRINT_AVERAGE FMT=%8.4f +DUMPGRID GRID=fine FILE=fine_grid FMT=%8.4f DUMPGRID GRID=interpol FILE=interpol FMT=%8.4f diff --git a/regtest/multicolvar/rt-dens/interpol.reference b/regtest/multicolvar/rt-dens/interpol.reference index 851a78ece..70c0d6189 100644 --- a/regtest/multicolvar/rt-dens/interpol.reference +++ b/regtest/multicolvar/rt-dens/interpol.reference @@ -1,5 +1,5 @@ #! FIELDS x interpol dinterpol_x -#! SET normalisation 0.0000 +#! SET normalisation 1.0000 #! SET min_x -2.5 #! SET max_x 2.5 #! SET nbins_x 100 diff --git a/regtest/multicolvar/rt-dens/plumed.dat b/regtest/multicolvar/rt-dens/plumed.dat index b4094dd1e..828d9bb5d 100644 --- a/regtest/multicolvar/rt-dens/plumed.dat +++ b/regtest/multicolvar/rt-dens/plumed.dat @@ -13,8 +13,8 @@ dens2b: MULTICOLVARDENS DATA=dens ORIGIN=1 DIR=x NBINS=50 CLEAR=2 BANDWIDTH=0.1 DUMPGRID GRID=dens2b STRIDE=2 FILE=dens2b FMT=%8.4f # Interpolate onto a finer grid and test -fine: MULTICOLVARDENS DATA=dens ORIGIN=1 DIR=x NBINS=100 BANDWIDTH=0.1 -interpol: INTERPOLATE_GRID GRID=dens2 GRID_BIN=100 +fine: MULTICOLVARDENS DATA=dens ORIGIN=1 DIR=x NBINS=100 STRIDE=4 BANDWIDTH=0.1 +interpol: INTERPOLATE_GRID GRID=dens2 STRIDE=4 GRID_BIN=100 DUMPGRID GRID=fine FILE=fine_grid FMT=%8.4f DUMPGRID GRID=interpol FILE=interpol FMT=%8.4f diff --git a/src/analysis/Histogram.cpp b/src/analysis/Histogram.cpp index f27c6535a..3a878a28b 100644 --- a/src/analysis/Histogram.cpp +++ b/src/analysis/Histogram.cpp @@ -117,8 +117,9 @@ private: public: static void registerKeywords( Keywords& keys ); explicit Histogram(const ActionOptions&ao); - bool prepareForTasks(); - void finishTaskSet(); + void prepareForAveraging(); + void performOperations( const bool& from_update ); + void finishAveraging(); bool isPeriodic(){ return false; } unsigned getNumberOfDerivatives(){ return getNumberOfArguments(); } void compute( const unsigned& , MultiValue& ) const ; @@ -132,6 +133,7 @@ void Histogram::registerKeywords( Keywords& keys ){ keys.add("compulsory","GRID_MAX","the upper bounds for the grid"); keys.add("optional","GRID_BIN","the number of bins for the grid"); keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)"); + keys.use("UPDATE_FROM"); keys.use("UPDATE_UNTIL"); } Histogram::Histogram(const ActionOptions&ao): @@ -166,31 +168,29 @@ kernel(NULL) plumed_assert( myhist ); myhist->addOneKernelEachTimeOnly(); // Create a task list for(unsigned i=0;i<mygrid->getNumberOfPoints();++i) addTaskToList(i); - finishGridSetup(); resizeFunctions(); checkRead(); + setAveragingAction( mygrid, myhist->noDiscreteKernels() ); checkRead(); } -bool Histogram::prepareForTasks(){ +void Histogram::prepareForAveraging(){ // Now fetch the kernel and the active points std::vector<double> point( getNumberOfArguments() ); for(unsigned i=0;i<point.size();++i) point[i]=getArgument(i); - unsigned num_neigh; std::vector<unsigned> neighbors; + unsigned num_neigh; std::vector<unsigned> neighbors(1); kernel = myhist->getKernelAndNeighbors( point, num_neigh, neighbors ); if( num_neigh>1 ){ // Activate relevant tasks deactivateAllTasks(); for(unsigned i=0;i<num_neigh;++i) taskFlags[neighbors[i]]=1; lockContributors(); - - // Calculate the grid at all relevant points - return true; } else { // This is used when we are not doing kernel density evaluation - mygrid->setGridElement( neighbors[0], 0, mygrid->getGridElement( neighbors[0], 0 ) + 1.0 ); - return false; + mygrid->setGridElement( neighbors[0], 0, mygrid->getGridElement( neighbors[0], 0 ) + cweight ); } } -void Histogram::finishTaskSet(){ +void Histogram::performOperations( const bool& from_update ){ plumed_dbg_assert( !myhist->noDiscreteKernels() ); } + +void Histogram::finishAveraging(){ delete kernel; } diff --git a/src/bias/ReweightBase.cpp b/src/bias/ReweightBase.cpp new file mode 100644 index 000000000..e0d13913e --- /dev/null +++ b/src/bias/ReweightBase.cpp @@ -0,0 +1,73 @@ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Copyright (c) 2011-2016 The plumed team + (see the PEOPLE file at the root of the distribution for a list of names) + + See http://www.plumed.org for more information. + + This file is part of plumed, version 2. + + plumed is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + plumed is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with plumed. If not, see <http://www.gnu.org/licenses/>. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +#include "core/PlumedMain.h" +#include "core/ActionSet.h" +#include "core/Atoms.h" +#include "ReweightBase.h" + +namespace PLMD { +namespace bias { + +void ReweightBase::registerKeywords(Keywords& keys){ + Action::registerKeywords( keys ); + ActionWithValue::registerKeywords( keys ); + ActionWithArguments::registerKeywords( keys ); + keys.setComponentsIntroduction("This action calculates the logarithm of a weight for reweighting"); + keys.add("optional","TEMP","the system temperature. This is not required if your MD code passes this quantity to PLUMED"); + keys.remove("NUMERICAL_DERIVATIVES"); +} + +ReweightBase::ReweightBase(const ActionOptions&ao): +Action(ao), +ActionWithValue(ao), +ActionWithArguments(ao) +{ + simtemp=0.; parse("TEMP",simtemp); + if(simtemp>0) simtemp*=plumed.getAtoms().getKBoltzmann(); + else simtemp=plumed.getAtoms().getKbT(); + if(simtemp==0) error("The MD engine does not pass the temperature to plumed so you have to specify it using TEMP"); + // Create something to hold the weight + addValue(); setNotPeriodic(); +} + +void ReweightBase::retrieveAllBiases( const std::string& lab, std::vector<Value*>& vals ){ + std::vector<ActionWithValue*> all=plumed.getActionSet().select<ActionWithValue*>(); + if( all.empty() ) error("your input file is not telling plumed to calculate anything"); + log.printf(" using the following biases in reweighting "); + for(unsigned j=0;j<all.size();j++){ + std::string flab; flab=all[j]->getLabel() + "." + lab; + if( all[j]->exists(flab) ){ + vals.push_back( all[j]->copyOutput(flab) ); + log.printf(" %s", flab.c_str()); + } + } + log.printf("\n"); + if( !vals.empty() ) requestArguments( vals ); +} + +void ReweightBase::calculate(){ + double weight = getLogWeight(); + setValue( weight ); +} + +} +} diff --git a/src/bias/ReweightBase.h b/src/bias/ReweightBase.h new file mode 100644 index 000000000..ce982b37d --- /dev/null +++ b/src/bias/ReweightBase.h @@ -0,0 +1,51 @@ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Copyright (c) 2011-2016 The plumed team + (see the PEOPLE file at the root of the distribution for a list of names) + + See http://www.plumed.org for more information. + + This file is part of plumed, version 2. + + plumed is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + plumed is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with plumed. If not, see <http://www.gnu.org/licenses/>. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +#ifndef __PLUMED_bias_ReweightBase_h +#define __PLUMED_bias_ReweightBase_h + +#include "core/ActionWithValue.h" +#include "core/ActionWithArguments.h" + +namespace PLMD { +namespace bias { + +class ReweightBase : +public ActionWithValue, +public ActionWithArguments +{ +protected: +/// The temperature at which you are running the simulation + double simtemp; +/// Retrieve all the values with a label ending in .lab + void retrieveAllBiases( const std::string& lab, std::vector<Value*>& vals ); +public: + static void registerKeywords(Keywords&); + explicit ReweightBase(const ActionOptions&ao); + unsigned getNumberOfDerivatives(){ return 0; } + void calculate(); + virtual double getLogWeight() const = 0; + void apply(){} +}; + +} +} +#endif diff --git a/src/bias/ReweightBias.cpp b/src/bias/ReweightBias.cpp new file mode 100644 index 000000000..db022301b --- /dev/null +++ b/src/bias/ReweightBias.cpp @@ -0,0 +1,67 @@ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Copyright (c) 2011-2016 The plumed team + (see the PEOPLE file at the root of the distribution for a list of names) + + See http://www.plumed.org for more information. + + This file is part of plumed, version 2. + + plumed is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + plumed is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with plumed. If not, see <http://www.gnu.org/licenses/>. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +#include "core/ActionRegister.h" +#include "ReweightBase.h" + +//+PLUMEDOC REWEIGHTING REWEIGHT_BIAS +/* + +\par Examples + +*/ +//+ENDPLUMEDOC + +namespace PLMD { +namespace bias { + +class ReweightBias : public ReweightBase { +private: +/// The biases we are using in reweighting and the args we store them separately + std::vector<Value*> biases; +public: + static void registerKeywords(Keywords&); + explicit ReweightBias(const ActionOptions&ao); + double getLogWeight() const ; +}; + +PLUMED_REGISTER_ACTION(ReweightBias,"REWEIGHT_BIAS") + +void ReweightBias::registerKeywords(Keywords& keys ){ + ReweightBase::registerKeywords( keys ); +} + +ReweightBias::ReweightBias(const ActionOptions&ao): +Action(ao), +ReweightBase(ao) +{ + retrieveAllBiases( "bias", biases ); + if( biases.empty() ) error("there does not appear to be a bias acting on your system"); +} + +double ReweightBias::getLogWeight() const { + // Retrieve the bias + double bias=0.0; for(unsigned i=0;i<biases.size();++i) bias+=biases[i]->get(); + return bias / simtemp; +} + +} +} diff --git a/src/bias/ReweightMetad.cpp b/src/bias/ReweightMetad.cpp new file mode 100644 index 000000000..78f66d52e --- /dev/null +++ b/src/bias/ReweightMetad.cpp @@ -0,0 +1,67 @@ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Copyright (c) 2011-2016 The plumed team + (see the PEOPLE file at the root of the distribution for a list of names) + + See http://www.plumed.org for more information. + + This file is part of plumed, version 2. + + plumed is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + plumed is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with plumed. If not, see <http://www.gnu.org/licenses/>. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +#include "core/ActionRegister.h" +#include "ReweightBase.h" + +//+PLUMEDOC REWEIGHTING REWEIGHT_METAD +/* + +\par Examples + +*/ +//+ENDPLUMEDOC + +namespace PLMD { +namespace bias { + +class ReweightMetad : public ReweightBase { +private: +/// The biases we are using in reweighting and the args we store them separately + std::vector<Value*> biases; +public: + static void registerKeywords(Keywords&); + explicit ReweightMetad(const ActionOptions&ao); + double getLogWeight() const ; +}; + +PLUMED_REGISTER_ACTION(ReweightMetad,"REWEIGHT_METAD") + +void ReweightMetad::registerKeywords(Keywords& keys ){ + ReweightBase::registerKeywords( keys ); +} + +ReweightMetad::ReweightMetad(const ActionOptions&ao): +Action(ao), +ReweightBase(ao) +{ + retrieveAllBiases( "rbias", biases ); + if( biases.empty() ) error("there does not appear to be a metadynamics bias acting on your system"); +} + +double ReweightMetad::getLogWeight() const { + // Retrieve the bias + double bias=0.0; for(unsigned i=0;i<biases.size();++i) bias+=biases[i]->get(); + return bias / simtemp; +} + +} +} diff --git a/src/bias/ReweightTemperature.cpp b/src/bias/ReweightTemperature.cpp new file mode 100644 index 000000000..e503ebfd7 --- /dev/null +++ b/src/bias/ReweightTemperature.cpp @@ -0,0 +1,78 @@ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Copyright (c) 2011-2016 The plumed team + (see the PEOPLE file at the root of the distribution for a list of names) + + See http://www.plumed.org for more information. + + This file is part of plumed, version 2. + + plumed is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + plumed is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with plumed. If not, see <http://www.gnu.org/licenses/>. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +#include "core/ActionRegister.h" +#include "core/PlumedMain.h" +#include "core/Atoms.h" +#include "ReweightBase.h" + +//+PLUMEDOC REWEIGHTING REWEIGHT_TEMP +/* + +\par Examples + +*/ +//+ENDPLUMEDOC + +namespace PLMD { +namespace bias { + +class ReweightTemperature : public ReweightBase { +private: +/// + double rtemp; +/// The biases we are using in reweighting and the args we store them separately + std::vector<Value*> biases; +public: + static void registerKeywords(Keywords&); + explicit ReweightTemperature(const ActionOptions&ao); + double getLogWeight() const ; +}; + +PLUMED_REGISTER_ACTION(ReweightTemperature,"REWEIGHT_TEMP") + +void ReweightTemperature::registerKeywords(Keywords& keys ){ + ReweightBase::registerKeywords( keys ); + keys.add("compulsory","REWEIGHT_TEMP","reweight data from a trajectory at one temperature and output the probability " + "distribution at a second temperature. This is not possible during postprocessing."); +} + +ReweightTemperature::ReweightTemperature(const ActionOptions&ao): +Action(ao), +ReweightBase(ao) +{ + plumed.getAtoms().setCollectEnergy(true); + parse("REWEIGHT_TEMP",rtemp); + log.printf(" reweighting simulation to probabilities at temperature %f\n",rtemp); + rtemp*=plumed.getAtoms().getKBoltzmann(); + + retrieveAllBiases( "bias", biases ); +} + +double ReweightTemperature::getLogWeight() const { + // Retrieve the bias + double bias=0.0; for(unsigned i=0;i<biases.size();++i) bias+=biases[i]->get(); + double energy=plumed.getAtoms().getEnergy()+bias; + return -( (1.0/rtemp) - (1.0/simtemp) )*(energy+bias); +} + +} +} diff --git a/src/core/ActionWithArguments.h b/src/core/ActionWithArguments.h index 1321e6745..a881fd917 100644 --- a/src/core/ActionWithArguments.h +++ b/src/core/ActionWithArguments.h @@ -57,7 +57,7 @@ public: /// Return a pointer to specific argument Value* getPntrToArgument( const unsigned n ); /// Returns the number of arguments - unsigned getNumberOfArguments() const ; + virtual unsigned getNumberOfArguments() const ; /// Takes the difference taking into account pbc for arg i double difference(int, double, double) const; /// Takes one value and brings it back into the pbc of argument i diff --git a/src/gridtools/ActionWithGrid.cpp b/src/gridtools/ActionWithGrid.cpp index 464fd5c33..65ad56a62 100644 --- a/src/gridtools/ActionWithGrid.cpp +++ b/src/gridtools/ActionWithGrid.cpp @@ -20,116 +20,52 @@ along with plumed. If not, see <http://www.gnu.org/licenses/>. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ #include "ActionWithGrid.h" +#include "core/PlumedMain.h" +#include "core/ActionSet.h" namespace PLMD { namespace gridtools { void ActionWithGrid::registerKeywords( Keywords& keys ){ - Action::registerKeywords( keys ); - ActionPilot::registerKeywords( keys ); - ActionAtomistic::registerKeywords( keys ); - ActionWithArguments::registerKeywords( keys ); - ActionWithVessel::registerKeywords( keys ); - keys.add("compulsory","STRIDE","1","the frequency with which the data should be collected and added to the grid"); - keys.add("compulsory","CLEAR","0","the frequency with which to clear all the accumulated data. The default value " - "of 0 implies that all the data will be used and that the grid will never be cleared"); + vesselbase::ActionWithAveraging::registerKeywords( keys ); keys.add("compulsory","BANDWIDTH","the bandwidths for kernel density esimtation"); keys.add("compulsory","KERNEL","gaussian","the kernel function you are using. More details on the kernels available " "in plumed plumed can be found in \\ref kernelfunctions."); - keys.addFlag("UNORMALIZED",false,"output the unormalized density on the grid."); } ActionWithGrid::ActionWithGrid( const ActionOptions& ao): Action(ao), -ActionPilot(ao), -ActionAtomistic(ao), -ActionWithArguments(ao), -ActionWithVessel(ao), -requiresNorm(false), +ActionWithAveraging(ao), mygrid(NULL) { - if( keywords.exists("CLEAR") ){ - parse("CLEAR",clearstride); - if( clearstride>0 ){ - if( clearstride%getStride()!=0 ) error("CLEAR parameter must be a multiple of STRIDE"); - log.printf(" clearing grid every %d steps \n",clearstride); - } - } } void ActionWithGrid::createGrid( const std::string& type, const std::string& inputstr ){ // Start creating the input for the grid - std::string vstring = inputstr + " "; + std::string vstring = inputstr; if( keywords.exists("KERNEL") ){ - vstring += getKeyword("KERNEL") + " " + getKeyword("BANDWIDTH"); + std::string kstring; parse("KERNEL",kstring); + if( kstring=="DISCRETE" ) vstring += " KERNEL=" + kstring; + else vstring += " KERNEL=" + kstring + " " + getKeyword("BANDWIDTH"); } - bool sumflag; parseFlag("UNORMALIZED",sumflag); - if( sumflag ) vstring += " UNORMALIZED"; - if( clearstride>0 ) vstring += " NOMEMORY"; vesselbase::VesselOptions da("mygrid","",-1,vstring,this); Keywords keys; gridtools::AverageOnGrid::registerKeywords( keys ); vesselbase::VesselOptions dar( da, keys ); if( type=="histogram" ){ - mygrid = new HistogramOnGrid(dar); requiresNorm=true; mygrid->setNorm(0); + mygrid = new HistogramOnGrid(dar); } else if( type=="average" ){ - mygrid = new AverageOnGrid(dar); requiresNorm=false; + mygrid = new AverageOnGrid(dar); } else if( type=="grid" ){ - mygrid = new GridVessel(dar); requiresNorm=false; + mygrid = new GridVessel(dar); } else { plumed_merror("no way to create grid of type " + type ); } } -void ActionWithGrid::finishGridSetup(){ - addVessel( mygrid ); -} - -void ActionWithGrid::lockRequests(){ - ActionAtomistic::lockRequests(); - ActionWithArguments::lockRequests(); -} - -void ActionWithGrid::unlockRequests(){ - ActionAtomistic::unlockRequests(); - ActionWithArguments::unlockRequests(); -} - -void ActionWithGrid::calculateNumericalDerivatives( PLMD::ActionWithValue* vv ){ - error("not possible to compute numerical derivatives for this action"); -} - -void ActionWithGrid::clearGrid(){ - mygrid->clear(); -} - -void ActionWithGrid::update(){ - if( getStep()==0 || !onStep() ) return; - // Clear if it is time to reset - if( mygrid ){ - if( mygrid->wasreset() ) clearGrid(); - } - // Run all the tasks (if required - if( prepareForTasks() ) runAllTasks(); - // This runs the jobs if we do not have a task list - else performGridOperations( true ); - // Update the norm if this is necessary - if( mygrid && requiresNorm ) mygrid->setNorm( 1 + mygrid->getNorm() ); - // Finish the tasks - finishTaskSet(); - // By resetting here we are ensuring that the grid will be cleared at the start of the next step - if( mygrid ){ - if( getStride()==0 || (clearstride>0 && getStep()%clearstride==0) ) mygrid->reset(); - } -} - void ActionWithGrid::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const { // Set the weight of this point - myvals.setValue( 0, 1.0 ); compute( current, myvals ); -} - -void ActionWithGrid::performGridOperations( const bool& from_update ){ - plumed_error(); + myvals.setValue( 0, cweight ); compute( current, myvals ); } } diff --git a/src/gridtools/ActionWithGrid.h b/src/gridtools/ActionWithGrid.h index 604ad38ac..32d53e30d 100644 --- a/src/gridtools/ActionWithGrid.h +++ b/src/gridtools/ActionWithGrid.h @@ -22,53 +22,30 @@ #ifndef __PLUMED_gridtools_ActionWithGrid_h #define __PLUMED_gridtools_ActionWithGrid_h -#include "core/ActionPilot.h" -#include "core/ActionAtomistic.h" -#include "core/ActionWithArguments.h" -#include "vesselbase/ActionWithVessel.h" +#include "vesselbase/ActionWithAveraging.h" #include "AverageOnGrid.h" namespace PLMD { namespace gridtools { -class ActionWithGrid : - public ActionPilot, - public ActionAtomistic, - public ActionWithArguments, - public vesselbase::ActionWithVessel -{ +class ActionWithGrid : public vesselbase::ActionWithAveraging { private: -/// Are we required to keep track of a normalization constant - bool requiresNorm; -/// The frequency with which to clear the grid - unsigned clearstride; /// The total number of bins std::vector<unsigned> nbins; /// The spacing between grid points std::vector<double> gspacing; -protected: +/// The weights we are going to use for reweighting + std::vector<Value*> weights; +protected: /// The grid vessel GridVessel* mygrid; /// Read in stuff that is specifically for the grid and create it void createGrid( const std::string& type, const std::string& inputstr ); -/// Finish the setup of the grid - void finishGridSetup(); public: static void registerKeywords( Keywords& keys ); explicit ActionWithGrid( const ActionOptions& ); - void lockRequests(); - void unlockRequests(); - void calculateNumericalDerivatives(PLMD::ActionWithValue*); - void calculate(){} - void apply(){} - void update(); - virtual void clearGrid(); - virtual bool prepareForTasks() = 0; - virtual void finishTaskSet() {}; void performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const ; virtual void compute( const unsigned& current, MultiValue& myvals ) const = 0; -/// This is used to perform all the tasks if we are not using the task list - virtual void performGridOperations( const bool& from_update ); }; } diff --git a/src/gridtools/ActionWithInputGrid.cpp b/src/gridtools/ActionWithInputGrid.cpp index d57ee97ae..8d2569c39 100644 --- a/src/gridtools/ActionWithInputGrid.cpp +++ b/src/gridtools/ActionWithInputGrid.cpp @@ -58,22 +58,21 @@ ingrid(NULL) log.printf(" using %uth component of grid calculated by action %s \n",mycomp,mves->getLabel().c_str() ); } -bool ActionWithInputGrid::prepareForTasks(){ +void ActionWithInputGrid::clearAverage(){ + mygrid->setBounds( ingrid->getMin(), ingrid->getMax(), mygrid->getNbin(), mygrid->getGridSpacing() ); + ActionWithAveraging::clearAverage(); +} + +void ActionWithInputGrid::prepareForAveraging(){ if( checkAllActive() ){ for(unsigned i=0;i<ingrid->getNumberOfPoints();++i){ if( ingrid->inactive(i) ) error("if FIND_CONTOUR is used with BUFFER option then other actions cannot be performed with grid"); } } - return (getFullNumberOfTasks()>0); -} - -void ActionWithInputGrid::runFinalJobs(){ - if( getStride()>0 ) return; - performGridOperations( false ); } -void ActionWithInputGrid::performGridOperations( const bool& from_update ){ - plumed_assert( !from_update ); prepareForTasks(); runAllTasks(); +void ActionWithInputGrid::performOperations( const bool& from_update ){ + prepareForAveraging(); runAllTasks(); } } diff --git a/src/gridtools/ActionWithInputGrid.h b/src/gridtools/ActionWithInputGrid.h index 433aa4019..42823df59 100644 --- a/src/gridtools/ActionWithInputGrid.h +++ b/src/gridtools/ActionWithInputGrid.h @@ -40,10 +40,10 @@ protected: public: static void registerKeywords( Keywords& keys ); explicit ActionWithInputGrid(const ActionOptions&ao); - bool prepareForTasks(); - void runFinalJobs(); + virtual void clearAverage(); + virtual void prepareForAveraging(); virtual bool checkAllActive() const { return true; } - virtual void performGridOperations( const bool& from_update ); + virtual void performOperations( const bool& from_update ); }; inline diff --git a/src/gridtools/AverageOnGrid.cpp b/src/gridtools/AverageOnGrid.cpp index 3167b53b7..0f8933f1c 100644 --- a/src/gridtools/AverageOnGrid.cpp +++ b/src/gridtools/AverageOnGrid.cpp @@ -49,23 +49,20 @@ void AverageOnGrid::accumulate( const unsigned& ipoint, const double& weight, co } double AverageOnGrid::getGridElement( const unsigned& ipoint, const unsigned& jelement ) const { - if( unormalised ) return data[nper*ipoint + jelement]; + if( noAverage() ) return getDataElement( nper*ipoint + jelement); - if( noderiv ) return data[nper*ipoint+jelement] / data[nper*(1+ipoint) - 1]; + if( jelement>=(nper-(dimension+1)) ) return getDataElement( nper*ipoint + jelement ); + + if( noderiv ) return getDataElement( nper*ipoint+jelement ) / getDataElement( nper*(1+ipoint) - 1); double rdenom = 1.0; - if( fabs(data[nper*(ipoint+1) -(dimension+1)])>epsilon ) rdenom = 1. / data[nper*(ipoint+1) - (dimension+1)]; + if( fabs(getDataElement( nper*(ipoint+1) -(dimension+1) ))>epsilon ) rdenom = 1. / getDataElement( nper*(ipoint+1) - (dimension+1) ); unsigned jderiv = jelement%(1+dimension); - if( jderiv==0 ) return rdenom*data[nper*ipoint+jelement]; + if( jderiv==0 ) return rdenom*getDataElement( nper*ipoint+jelement ); unsigned jfloor = std::floor( jelement / (1+dimension) ); - return rdenom*data[nper*ipoint+jelement] - rdenom*rdenom*data[nper*ipoint+jfloor]*data[nper*(ipoint+1) - (dimension+1) + jderiv ]; -} - -double AverageOnGrid::getGridElementForPrint( const unsigned& ipoint, const unsigned& jelement ) const { - plumed_assert( bounds_set && ipoint<npoints && jelement<nper && active[ipoint] ); - return data[nper*ipoint + jelement]; + return rdenom*getDataElement( nper*ipoint+jelement ) - rdenom*rdenom*getDataElement(nper*ipoint+jfloor)*getDataElement(nper*(ipoint+1) - (dimension+1) + jderiv); } } diff --git a/src/gridtools/AverageOnGrid.h b/src/gridtools/AverageOnGrid.h index 5229e0e52..7288526fa 100644 --- a/src/gridtools/AverageOnGrid.h +++ b/src/gridtools/AverageOnGrid.h @@ -33,7 +33,6 @@ public: explicit AverageOnGrid( const vesselbase::VesselOptions& da ); void accumulate( const unsigned& ipoint, const double& weight, const double& dens, const std::vector<double>& der, std::vector<double>& buffer ) const ; double getGridElement( const unsigned& ipoint, const unsigned& jelement ) const ; - double getGridElementForPrint( const unsigned& ipoint, const unsigned& jelement ) const ; unsigned getNumberOfComponents() const ; }; diff --git a/src/gridtools/ContourFindingBase.cpp b/src/gridtools/ContourFindingBase.cpp index be63da700..7d3d2ccad 100644 --- a/src/gridtools/ContourFindingBase.cpp +++ b/src/gridtools/ContourFindingBase.cpp @@ -80,7 +80,7 @@ mydata(NULL) } } -void ContourFindingBase::finishTaskSet(){ +void ContourFindingBase::finishAveraging(){ // And this looks after the output if( mydata ){ std::vector<double> point( 1 + ingrid->getDimension() ); diff --git a/src/gridtools/ContourFindingBase.h b/src/gridtools/ContourFindingBase.h index 90a6c0d1e..2dbf0dbbc 100644 --- a/src/gridtools/ContourFindingBase.h +++ b/src/gridtools/ContourFindingBase.h @@ -55,7 +55,7 @@ public: /// Number of quantities is the number of points in each point on the grid virtual unsigned getNumberOfQuantities() const { return 1 + ingrid->getDimension(); } /// This does output if needs be - void finishTaskSet(); + void finishAveraging(); }; inline diff --git a/src/gridtools/ConvertToFES.cpp b/src/gridtools/ConvertToFES.cpp index d91e656eb..1712f159c 100644 --- a/src/gridtools/ConvertToFES.cpp +++ b/src/gridtools/ConvertToFES.cpp @@ -54,7 +54,8 @@ PLUMED_REGISTER_ACTION(ConvertToFES,"CONVERT_TO_FES") void ConvertToFES::registerKeywords( Keywords& keys ){ ActionWithInputGrid::registerKeywords( keys ); keys.add("optional","TEMP","the temperature at which you are operating"); - keys.remove("STRIDE"); keys.remove("KERNEL"); keys.remove("BANDWIDTH"); keys.remove("CLEAR"); + keys.remove("STRIDE"); keys.remove("KERNEL"); keys.remove("BANDWIDTH"); + keys.remove("LOGWEIGHTS"); keys.remove("CLEAR"); } ConvertToFES::ConvertToFES(const ActionOptions&ao): @@ -68,7 +69,7 @@ ActionWithInputGrid(ao) if( ingrid->noDerivatives() ) mygrid->setNoDerivatives(); std::vector<double> fspacing; mygrid->setBounds( ingrid->getMin(), ingrid->getMax(), ingrid->getNbin(), fspacing); - finishGridSetup(); resizeFunctions(); + setAveragingAction( mygrid, true ); simtemp=0.; parse("TEMP",simtemp); if(simtemp>0) simtemp*=plumed.getAtoms().getKBoltzmann(); diff --git a/src/gridtools/DumpCube.cpp b/src/gridtools/DumpCube.cpp index 871bfc68a..67109b181 100644 --- a/src/gridtools/DumpCube.cpp +++ b/src/gridtools/DumpCube.cpp @@ -20,7 +20,7 @@ along with plumed. If not, see <http://www.gnu.org/licenses/>. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ #include "core/ActionRegister.h" -#include "ActionWithInputGrid.h" +#include "GridPrintingBase.h" #include "tools/OFile.h" //+PLUMEDOC GRIDANALYSIS DUMPCUBE @@ -35,46 +35,42 @@ Output a three dimensional grid using the Gaussian cube file format. namespace PLMD { namespace gridtools { -class DumpCube : public ActionWithInputGrid { +class DumpCube : public GridPrintingBase { private: - std::string fmt, filename; + unsigned mycomp; public: static void registerKeywords( Keywords& keys ); explicit DumpCube(const ActionOptions&ao); - void performGridOperations( const bool& from_update ); - unsigned getNumberOfDerivatives(){ return 0; } - void compute( const unsigned& , MultiValue& ) const {} - bool isPeriodic(){ return false; } + void printGrid( OFile& ofile ) const ; }; PLUMED_REGISTER_ACTION(DumpCube,"DUMPCUBE") void DumpCube::registerKeywords( Keywords& keys ){ - ActionWithInputGrid::registerKeywords( keys ); - keys.add("compulsory","FILE","density","the file on which to write the grid."); - keys.add("optional","FMT","the format that should be used to output real numbers"); + GridPrintingBase::registerKeywords( keys ); + keys.add("optional","COMPONENT","if your input is a vector field use this to specifiy the component of the input vector field for which you wish to output"); } DumpCube::DumpCube(const ActionOptions&ao): Action(ao), -ActionWithInputGrid(ao), -fmt("%f") +GridPrintingBase(ao) { + fmt = fmt + " "; if( ingrid->getDimension()!=3 ) error("cannot print cube file if grid does not contain three dimensional data"); - parse("FMT",fmt); fmt=fmt +" "; parse("FILE",filename); - if(filename.length()==0) error("name out output file was not specified"); - log.printf(" outputting grid to file named %s with format %s \n",filename.c_str(), fmt.c_str() ); + if( ingrid->getNumberOfComponents()==1 ){ + mycomp=0; + } else { + int tcomp=-1; parse("COMPONENT",tcomp); + if( tcomp<0 ) error("component of vector field was not specified - use COMPONENT keyword"); + mycomp=tcomp*(1+ingrid->getDimension()); if( ingrid->noDerivatives() ) mycomp=tcomp; + log.printf(" using %dth component of grid \n",tcomp ); + } checkRead(); } -void DumpCube::performGridOperations( const bool& from_update ){ - if( !from_update && getStride()>0 ) return ; - OFile ofile; ofile.link(*this); - if( from_update ) ofile.setBackupString("analysis"); - ofile.open( filename ); - +void DumpCube::printGrid( OFile& ofile ) const { double lunit = ingrid->getCubeUnits(); ofile.printf("PLUMED CUBE FILE\n"); @@ -90,14 +86,12 @@ void DumpCube::performGridOperations( const bool& from_update ){ for(pp[0]=0;pp[0]<nbin[0];++pp[0]){ for(pp[1]=0;pp[1]<nbin[1];++pp[1]){ for(pp[2]=0;pp[2]<nbin[2];++pp[2]){ - ofile.printf(fmt.c_str(), getFunctionValue(pp) ); + ofile.printf(fmt.c_str(), ingrid->getGridElement( ingrid->getIndex(pp), mycomp ) ); if(pp[2]%6==5) ofile.printf("\n"); } ofile.printf("\n"); } } - - ofile.close(); } } diff --git a/src/gridtools/DumpGrid.cpp b/src/gridtools/DumpGrid.cpp index c2ebec60a..150378ca1 100644 --- a/src/gridtools/DumpGrid.cpp +++ b/src/gridtools/DumpGrid.cpp @@ -19,10 +19,8 @@ You should have received a copy of the GNU Lesser General Public License along with plumed. If not, see <http://www.gnu.org/licenses/>. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ -#include "ActionWithInputGrid.h" +#include "GridPrintingBase.h" #include "core/ActionRegister.h" -#include "AverageOnGrid.h" -#include "tools/IFile.h" #include "tools/OFile.h" namespace PLMD { @@ -37,50 +35,27 @@ Output the function on the grid to a file with the PLUMED grid format. */ //+ENDPLUMEDOC -class DumpGrid : public ActionWithInputGrid { -private: - bool printav; - std::string fmt, filename; +class DumpGrid : public GridPrintingBase { public: static void registerKeywords( Keywords& keys ); explicit DumpGrid(const ActionOptions&ao); - void performGridOperations( const bool& from_update ); - unsigned getNumberOfDerivatives(){ return 0; } - void compute( const unsigned& , MultiValue& ) const {} - bool isPeriodic(){ return false; } + void printGrid( OFile& ofile ) const ; }; PLUMED_REGISTER_ACTION(DumpGrid,"DUMPGRID") void DumpGrid::registerKeywords( Keywords& keys ){ - ActionWithInputGrid::registerKeywords( keys ); - keys.add("compulsory","FILE","density","the file on which to write the grid."); - keys.add("optional","FMT","the format that should be used to output real numbers"); - keys.addFlag("PRINT_AVERAGE",false,"if your input is a \\ref MULTICOLVARDENS output the average in the grid file."); + GridPrintingBase::registerKeywords( keys ); } DumpGrid::DumpGrid(const ActionOptions&ao): Action(ao), -ActionWithInputGrid(ao), -printav(false), -fmt("%f") +GridPrintingBase(ao) { - AverageOnGrid* myav = dynamic_cast<AverageOnGrid*>( ingrid ); - if( myav ) parseFlag("PRINT_AVERAGE",printav); - - parse("FMT",fmt); fmt=" "+fmt; parse("FILE",filename); - if(filename.length()==0) error("name out output file was not specified"); - log.printf(" outputting grid to file named %s with format %s \n",filename.c_str(), fmt.c_str() ); - checkRead(); + fmt = " " + fmt; checkRead(); } -void DumpGrid::performGridOperations( const bool& from_update ){ - if( !from_update && getStride()>0 ) return ; - - OFile ofile; ofile.link(*this); - if ( from_update ) ofile.setBackupString("analysis"); - ofile.open( filename ); - +void DumpGrid::printGrid( OFile& ofile ) const { ofile.addConstantField("normalisation"); for(unsigned i=0;i<ingrid->getDimension();++i){ ofile.addConstantField("min_" + ingrid->getComponentName(i) ); @@ -94,7 +69,7 @@ void DumpGrid::performGridOperations( const bool& from_update ){ for(unsigned i=0;i<ingrid->getNumberOfPoints();++i){ ingrid->getIndices( i, ind ); if(i>0 && ingrid->getDimension()==2 && ind[ingrid->getDimension()-2]==0) ofile.printf("\n"); - ofile.fmtField(fmt); ofile.printField("normalisation", ingrid->norm ); + ofile.fmtField(fmt); ofile.printField("normalisation", ingrid->getNorm() ); for(unsigned j=0;j<ingrid->getDimension();++j){ ofile.printField("min_" + ingrid->getComponentName(j), ingrid->getMin()[j] ); ofile.printField("max_" + ingrid->getComponentName(j), ingrid->getMax()[j] ); @@ -105,19 +80,11 @@ void DumpGrid::performGridOperations( const bool& from_update ){ // Retrieve and print the grid coordinates ingrid->getGridPointCoordinates(i, xx ); for(unsigned j=0;j<ingrid->getDimension();++j){ ofile.fmtField(fmt); ofile.printField(ingrid->getComponentName(j),xx[j]); } - if( printav ){ - unsigned nnorm=ingrid->dimension+1; if( ingrid->noderiv ) nnorm=1; - for(unsigned j=0;j<ingrid->getNumberOfQuantities()-nnorm;++j){ - ofile.fmtField(fmt); ofile.printField(ingrid->arg_names[ingrid->dimension+j], ingrid->getGridElement( i, j ) ); - } - } else { - for(unsigned j=0;j<ingrid->getNumberOfQuantities();++j){ - ofile.fmtField(fmt); ofile.printField(ingrid->arg_names[ingrid->dimension+j], ingrid->getGridElementForPrint( i, j ) ); - } + for(unsigned j=0;j<ingrid->getNumberOfQuantities();++j){ + ofile.fmtField(fmt); ofile.printField(ingrid->arg_names[ingrid->dimension+j], ingrid->getGridElement( i, j ) ); } ofile.printField(); } - ofile.close(); } } diff --git a/src/gridtools/FindContour.cpp b/src/gridtools/FindContour.cpp index bb7058a85..a60c2ac59 100644 --- a/src/gridtools/FindContour.cpp +++ b/src/gridtools/FindContour.cpp @@ -42,10 +42,10 @@ public: static void registerKeywords( Keywords& keys ); explicit FindContour(const ActionOptions&ao); bool checkAllActive() const { return gbuffer==0; } - bool prepareForTasks(); + void prepareForAveraging(); bool isPeriodic(){ return false; } void compute( const unsigned& current, MultiValue& myvals ) const ; - void finishTaskSet(); + void finishAveraging(); }; PLUMED_REGISTER_ACTION(FindContour,"FIND_CONTOUR") @@ -67,7 +67,7 @@ firsttime(true) checkRead(); } -bool FindContour::prepareForTasks(){ +void FindContour::prepareForAveraging(){ // Create a task list if first time if( firsttime ){ for(unsigned i=0;i<ingrid->getDimension()*ingrid->getNumberOfPoints();++i) addTaskToList( i ); @@ -106,7 +106,7 @@ bool FindContour::prepareForTasks(){ else ind[j]-=1; } } - lockContributors(); return true; + lockContributors(); } void FindContour::compute( const unsigned& current, MultiValue& myvals ) const { @@ -126,8 +126,8 @@ void FindContour::compute( const unsigned& current, MultiValue& myvals ) const { for(unsigned i=0;i<ingrid->getDimension();++i) myvals.setValue( 1+i, point[i] ); } -void FindContour::finishTaskSet(){ - ContourFindingBase::finishTaskSet(); +void FindContour::finishAveraging(){ + ContourFindingBase::finishAveraging(); // And update the list of active grid points if( gbuffer>0 ){ std::vector<unsigned> neighbours; unsigned num_neighbours; diff --git a/src/gridtools/FindContourSurface.cpp b/src/gridtools/FindContourSurface.cpp index dce11fed5..cc10f077a 100644 --- a/src/gridtools/FindContourSurface.cpp +++ b/src/gridtools/FindContourSurface.cpp @@ -47,9 +47,10 @@ public: explicit FindContourSurface(const ActionOptions&ao); unsigned getNumberOfQuantities() const { return 2; } bool checkAllActive() const { return gbuffer==0; } - bool prepareForTasks(); + void clearAverage(); + void prepareForAveraging(); void compute( const unsigned& current, MultiValue& myvals ) const ; - void finishTaskSet(); + void finishAveraging(); }; PLUMED_REGISTER_ACTION(FindContourSurface,"FIND_CONTOUR_SURFACE") @@ -94,18 +95,23 @@ ones(ingrid->getDimension(),1) for(unsigned i=1;i<gdirs.size();++i){ if( ingrid->isPeriodic(gdirs[i]) ) vstring+=",T"; else vstring+=",F"; } - createGrid( "grid", vstring ); mygrid->setNoDerivatives(); finishGridSetup(); + createGrid( "grid", vstring ); mygrid->setNoDerivatives(); + setAveragingAction( mygrid, true ); } -bool FindContourSurface::prepareForTasks(){ +void FindContourSurface::clearAverage(){ // Set the boundaries of the output grid std::vector<double> fspacing; std::vector<unsigned> snbins( ingrid->getDimension()-1 ); std::vector<std::string> smin( ingrid->getDimension()-1 ), smax( ingrid->getDimension()-1 ); for(unsigned i=0;i<gdirs.size();++i){ smin[i]=ingrid->getMin()[gdirs[i]]; smax[i]=ingrid->getMax()[gdirs[i]]; snbins[i]=ingrid->getNbin()[gdirs[i]]; - } + } mygrid->setBounds( smin, smax, snbins, fspacing); resizeFunctions(); + ActionWithAveraging::clearAverage(); +} + +void FindContourSurface::prepareForAveraging(){ // Create a task list if first time if( firsttime ){ std::vector<unsigned> find( ingrid->getDimension() ); @@ -124,11 +130,11 @@ bool FindContourSurface::prepareForTasks(){ direction.resize( ingrid->getDimension(), 0 ); direction[dir_n] = 0.999999999*ingrid->getGridSpacing()[dir_n]; } - firsttime=false; return true; + firsttime=false; } -void FindContourSurface::finishTaskSet(){ - ContourFindingBase::finishTaskSet(); +void FindContourSurface::finishAveraging(){ + ContourFindingBase::finishAveraging(); // And update the list of active grid points if( gbuffer>0 ){ std::vector<double> dx( ingrid->getGridSpacing() ); diff --git a/src/gridtools/FourierTransform.cpp b/src/gridtools/FourierTransform.cpp index a6ec20e2b..9a363c9de 100644 --- a/src/gridtools/FourierTransform.cpp +++ b/src/gridtools/FourierTransform.cpp @@ -76,9 +76,9 @@ public: static void registerKeywords( Keywords& keys ); explicit FourierTransform(const ActionOptions&ao); #ifndef __PLUMED_HAS_FFTW - void performOperationsWithGrid( const bool& from_update ){} + void performOperations( const bool& from_update ){} #else - void performOperationsWithGrid( const bool& from_update ); + void performOperations( const bool& from_update ); #endif unsigned getNumberOfDerivatives(){ return 0; } void compute( const unsigned& , MultiValue& ) const {} @@ -173,7 +173,7 @@ fourier_params(2) } #ifdef __PLUMED_HAS_FFTW -void FourierTransform::performOperationsWithGrid( const bool& from_update ){ +void FourierTransform::performOperations( const bool& from_update ){ // Spacing of the real grid std::vector<double> g_spacing ( ingrid->getGridSpacing() ); diff --git a/src/gridtools/GridPrintingBase.cpp b/src/gridtools/GridPrintingBase.cpp new file mode 100644 index 000000000..c2d253c04 --- /dev/null +++ b/src/gridtools/GridPrintingBase.cpp @@ -0,0 +1,76 @@ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Copyright (c) 2014,2015 The plumed team + (see the PEOPLE file at the root of the distribution for a list of names) + + See http://www.plumed-code.org for more information. + + This file is part of plumed, version 2. + + plumed is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + plumed is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with plumed. If not, see <http://www.gnu.org/licenses/>. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +#include "GridPrintingBase.h" +#include "core/PlumedMain.h" +#include "core/ActionSet.h" +#include "vesselbase/ActionWithVessel.h" + +namespace PLMD { +namespace gridtools { + +void GridPrintingBase::registerKeywords( Keywords& keys ){ + Action::registerKeywords( keys ); ActionPilot::registerKeywords( keys ); + keys.add("compulsory","GRID","the action that creates the grid you would like to output"); + keys.add("compulsory","STRIDE","0","the frequency with which the grid should be output to the file. The default " + "value of 0 ensures that the grid is only output at the end of the trajectory"); + keys.add("compulsory","FILE","density","the file on which to write the grid."); + keys.add("optional","FMT","the format that should be used to output real numbers"); +} + +GridPrintingBase::GridPrintingBase(const ActionOptions&ao): +Action(ao), +ActionPilot(ao), +fmt("%f") +{ + std::string mlab; parse("GRID",mlab); + vesselbase::ActionWithVessel* mves= plumed.getActionSet().selectWithLabel<vesselbase::ActionWithVessel*>(mlab); + if(!mves) error("action labelled " + mlab + " does not exist or does not have vessels"); + addDependency(mves); + + for(unsigned i=0;i<mves->getNumberOfVessels();++i){ + ingrid=dynamic_cast<GridVessel*>( mves->getPntrToVessel(i) ); + if( ingrid ) break; + } + if( !ingrid ) error("input action does not calculate a grid"); + + parse("FMT",fmt); parse("FILE",filename); + if(filename.length()==0) error("name out output file was not specified"); + log.printf(" outputting grid calculated by action %s to file named %s with format %s \n",mves->getLabel().c_str(),filename.c_str(), fmt.c_str() ); +} + +void GridPrintingBase::update(){ + if( getStep()==0 || getStride()==0 ) return ; + + OFile ofile; ofile.link(*this); + ofile.setBackupString("analysis"); + ofile.open( filename ); printGrid( ofile ); ofile.close(); +} + +void GridPrintingBase::runFinalJobs(){ + if( getStride()>0 ) return; + + OFile ofile; ofile.link(*this); + ofile.open( filename ); printGrid( ofile ); ofile.close(); +} + +} +} diff --git a/src/gridtools/GridPrintingBase.h b/src/gridtools/GridPrintingBase.h new file mode 100644 index 000000000..b6444b022 --- /dev/null +++ b/src/gridtools/GridPrintingBase.h @@ -0,0 +1,48 @@ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Copyright (c) 2014,2015 The plumed team + (see the PEOPLE file at the root of the distribution for a list of names) + + See http://www.plumed-code.org for more information. + + This file is part of plumed, version 2. + + plumed is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + plumed is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with plumed. If not, see <http://www.gnu.org/licenses/>. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +#ifndef __PLUMED_gridtools_GridPrintingBase_h +#define __PLUMED_gridtools_GridPrintingBase_h + +#include "core/ActionPilot.h" +#include "GridVessel.h" +#include "tools/OFile.h" + +namespace PLMD { +namespace gridtools { + +class GridPrintingBase : public ActionPilot { +protected: + GridVessel* ingrid; + std::string fmt, filename; +public: + static void registerKeywords( Keywords& keys ); + explicit GridPrintingBase(const ActionOptions&ao); + void calculate(){} + void apply(){} + void update(); + void runFinalJobs(); + virtual void printGrid( OFile& ofile ) const=0; +}; + +} +} +#endif diff --git a/src/gridtools/GridVessel.cpp b/src/gridtools/GridVessel.cpp index 2f7288590..dfd383189 100644 --- a/src/gridtools/GridVessel.cpp +++ b/src/gridtools/GridVessel.cpp @@ -27,20 +27,16 @@ namespace PLMD { namespace gridtools { void GridVessel::registerKeywords( Keywords& keys ){ - Vessel::registerKeywords( keys ); + AveragingVessel::registerKeywords( keys ); keys.add("compulsory","COMPONENTS","the names of the components in the vector"); keys.add("compulsory","COORDINATES","the names of the coordinates of the grid"); keys.add("compulsory","PBC","is the grid periodic in each direction or not"); - keys.addFlag("NOMEMORY",false,"should the data in the grid be deleted after print/analysis"); - keys.addFlag("UNORMALIZED",false,"don't normalise grid"); } GridVessel::GridVessel( const vesselbase::VesselOptions& da ): -Vessel(da), +AveragingVessel(da), bounds_set(false), cube_units(1.0), -wascleared(true), -norm(0.0), noderiv(false) { std::vector<std::string> compnames; parseVector("COMPONENTS",compnames); @@ -48,8 +44,6 @@ noderiv(false) dimension=coordnames.size(); std::vector<std::string> spbc( dimension ); parseVector("PBC",spbc); str_min.resize( dimension); str_max.resize( dimension ); - parseFlag("NOMEMORY",nomemory); parseFlag("UNORMALIZED",unormalised); - foundprint=nomemory; unsigned n=0; nper=compnames.size()*( 1 + coordnames.size() ); arg_names.resize( coordnames.size() + compnames.size()*( 1 + coordnames.size() ) ); @@ -90,9 +84,10 @@ void GridVessel::setBounds( const std::vector<std::string>& smin, const std::vec Tools::convert( str_min[i], min[i] ); Tools::convert( str_max[i], max[i] ); if( spacing.size()==dimension && binsin.size()==dimension ){ - unsigned spc = std::floor(( max[i] - min[i] ) / spacing[i]) + 1; - if( spc>binsin[i] ) nbin[i]=spc; - else nbin[i]=binsin[i]; + double range = max[i] - min[i]; unsigned spc = std::floor( range / spacing[i]); + // This check ensures that nbins is set correctly if spacing is set the same as the number of bins + if( fabs( binsin[i]*spacing[i]-range )>epsilon ) spc += 1; + if( spc>binsin[i] ) nbin[i]=spc; else nbin[i]=binsin[i]; } else if( binsin.size()==dimension ) nbin[i]=binsin[i]; else if( spacing.size()==dimension ) nbin[i] = std::floor(( max[i] - min[i] ) / spacing[i]) + 1; else plumed_error(); @@ -101,6 +96,7 @@ void GridVessel::setBounds( const std::vector<std::string>& smin, const std::vec stride[i]=npoints; npoints*=nbin[i]; } + resize(); // Always resize after setting new bounds as grid size may have have changed } std::string GridVessel::description(){ @@ -123,11 +119,8 @@ std::string GridVessel::description(){ void GridVessel::resize(){ plumed_massert( nper>0, "Number of datapoints at each grid point has not been set"); - resizeBuffer( getNumberOfBufferPoints()*nper ); - if( data.size()!=npoints*nper ){ - data.resize( npoints*nper, 0 ); - active.resize( npoints, true ); - } + resizeBuffer( getNumberOfBufferPoints()*nper ); setDataSize( npoints*nper ); + if( active.size()!=npoints) active.resize( npoints, true ); } unsigned GridVessel::getIndex( const std::vector<unsigned>& indices ) const { @@ -198,16 +191,12 @@ void GridVessel::getSplineNeighbors( const unsigned& mybox, std::vector<unsigned double GridVessel::getGridElement( const unsigned& ipoint, const unsigned& jelement ) const { plumed_assert( bounds_set && ipoint<npoints && jelement<nper && active[ipoint] ); - return data[ nper*ipoint + jelement ]; -} - -double GridVessel::getGridElementForPrint( const unsigned& ipoint, const unsigned& jelement ) const { - return getGridElement( ipoint, jelement ); + return getDataElement( nper*ipoint + jelement ); } void GridVessel::setGridElement( const unsigned& ipoint, const unsigned& jelement, const double& value ){ plumed_dbg_assert( bounds_set && ipoint<npoints && jelement<nper ); - wascleared=false; data[ nper*ipoint + jelement ] = value; + setDataElement( nper*ipoint + jelement, value ); } void GridVessel::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const { @@ -215,10 +204,6 @@ void GridVessel::calculate( const unsigned& current, MultiValue& myvals, std::ve for(unsigned i=0;i<nper;++i) buffer[bufstart + nper*current + i] += myvals.get(i+1); } -void GridVessel::finish( const std::vector<double>& buffer ){ - wascleared=false; for(unsigned i=0;i<data.size();++i) data[i]+=buffer[bufstart + i]; -} - double GridVessel::getGridElement( const std::vector<unsigned>& indices, const unsigned& jelement ) const { return getGridElement( getIndex( indices ), jelement ); } @@ -285,15 +270,6 @@ void GridVessel::getNeighbors( const std::vector<unsigned>& indices, const std:: } } -void GridVessel::reset(){ - wascleared=true; -} - -void GridVessel::clear(){ - plumed_assert( wasreset() ); - norm=0; data.assign( data.size(), 0.0 ); -} - void GridVessel::setCubeUnits( const double& units ){ cube_units=units; } diff --git a/src/gridtools/GridVessel.h b/src/gridtools/GridVessel.h index 0cb5dfb09..83a215633 100644 --- a/src/gridtools/GridVessel.h +++ b/src/gridtools/GridVessel.h @@ -25,15 +25,13 @@ #include <string> #include <cstring> #include <vector> -#include "vesselbase/Vessel.h" +#include "vesselbase/AveragingVessel.h" namespace PLMD { namespace gridtools { -class GridVessel : public vesselbase::Vessel { +class GridVessel : public vesselbase::AveragingVessel { friend class ActionWithInputGrid; -friend class AverageOnGrid; -friend class GridFunction; friend class DumpGrid; private: /// Have the minimum and maximum for the grid been set @@ -53,18 +51,10 @@ private: /// The grid point that was requested last by getGridPointCoordinates unsigned currentGridPoint; protected: -/// The grid was recently cleared and bounds can be set - bool wascleared; /// Do we have derivatives bool noderiv; /// The names of the various columns in the grid file std::vector<std::string> arg_names; -/// The normalisation constant to use - double norm; -/// Are we deleting the data after print - bool nomemory; -/// Are we outputting unormalised data - bool unormalised; /// The number of pieces of information we are storing for each /// point in the grid unsigned nper; @@ -78,8 +68,6 @@ protected: unsigned dimension; /// Which grid points are we actively accumulating std::vector<bool> active; -/// The grid with all the data values on it - std::vector<double> data; /// Convert a point in space the the correspoinding grid point unsigned getIndex( const std::vector<double>& p ) const ; public: @@ -138,7 +126,6 @@ public: double getCellVolume() const ; /// Get the value of the ith grid element virtual double getGridElement( const unsigned&, const unsigned& ) const ; - virtual double getGridElementForPrint( const unsigned&, const unsigned& ) const ; /// Get the set of points neighouring a particular location in space void getNeighbors( const std::vector<double>& pp, const std::vector<unsigned>& nneigh, unsigned& num_neighbours, std::vector<unsigned>& neighbors ) const ; @@ -153,33 +140,20 @@ public: double getGridExtent( const unsigned& i ) const ; /// Copy data from the action into the grid virtual void calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const ; -/// Copy data from an accumulated buffer into the grid - virtual void finish( const std::vector<double>& ); -/// Clear all the data stored on the grid - virtual void clear(); -/// Reset the grid so that it is cleared at start of next time it is calculated - virtual void reset(); /// This ensures that Gaussian cube fies are in correct units void setCubeUnits( const double& units ); /// This ensures that Gaussian cube files are in correct units double getCubeUnits() const ; - virtual void switchOffNormalisation(){} /// Return a string containing the input to the grid so we can clone it std::string getInputString() const ; /// Does this have derivatives bool noDerivatives() const ; /// Get the value and derivatives at a particular location using spline interpolation double getValueAndDerivatives( const std::vector<double>& x, const unsigned& ind, std::vector<double>& der ) const ; -/// Was the grid cleared on the last step - bool wasreset() const ; /// Deactivate all the grid points void activateThesePoints( const std::vector<bool>& to_activate ); /// Is this point active bool inactive( const unsigned& ip ) const ; -/// Functions for dealing with normalisation constant - void setNorm( const double& snorm ); - double getNorm() const ; - bool applyForce( std::vector<double>& forces ){ return false; } }; inline @@ -234,27 +208,12 @@ bool GridVessel::noDerivatives() const { return noderiv; } -inline -bool GridVessel::wasreset() const { - return wascleared; -} - inline bool GridVessel::inactive( const unsigned& ip ) const { plumed_dbg_assert( ip<npoints ); return !active[ip]; } -inline -void GridVessel::setNorm( const double& snorm ){ - norm=snorm; -} - -inline -double GridVessel::getNorm() const { - return norm; -} - inline const std::vector<unsigned>& GridVessel::getStride() const { return stride; diff --git a/src/gridtools/HistogramOnGrid.cpp b/src/gridtools/HistogramOnGrid.cpp index 36725555b..a6468de4b 100644 --- a/src/gridtools/HistogramOnGrid.cpp +++ b/src/gridtools/HistogramOnGrid.cpp @@ -46,6 +46,10 @@ discrete(false) } } +bool HistogramOnGrid::noDiscreteKernels() const { + return !discrete; +} + void HistogramOnGrid::setBounds( const std::vector<std::string>& smin, const std::vector<std::string>& smax, const std::vector<unsigned>& nbins, const std::vector<double>& spacing ){ GridVessel::setBounds( smin, smax, nbins, spacing ); @@ -103,7 +107,6 @@ void HistogramOnGrid::calculate( const unsigned& current, MultiValue& myvals, st } else { std::vector<Value*> vv( getVectorOfValues() ); - unsigned ntot=nper*getNumberOfPoints(); double newval; std::vector<double> xx( dimension ); for(unsigned i=0;i<num_neigh;++i){ unsigned ineigh=neighbors[i]; @@ -126,19 +129,13 @@ void HistogramOnGrid::accumulate( const unsigned& ipoint, const double& weight, void HistogramOnGrid::finish( const std::vector<double>& buffer ){ if( addOneKernelAtATime ){ - wascleared=false; for(unsigned i=0;i<getAction()->getCurrentNumberOfActiveTasks();++i){ - for(unsigned j=0;j<nper;++j) data[nper*getAction()->getActiveTask(i)+j]+=buffer[bufstart+i*nper+j]; + for(unsigned j=0;j<nper;++j) addDataElement( nper*getAction()->getActiveTask(i)+j, buffer[bufstart+i*nper+j] ); } } else { GridVessel::finish( buffer ); } } -double HistogramOnGrid::getGridElement( const unsigned& ipoint, const unsigned& jelement ) const { - if( unormalised ) return GridVessel::getGridElement( ipoint, jelement ); - return GridVessel::getGridElement( ipoint, jelement ) / norm; -} - } } diff --git a/src/gridtools/HistogramOnGrid.h b/src/gridtools/HistogramOnGrid.h index 5670118df..f26d07c1f 100644 --- a/src/gridtools/HistogramOnGrid.h +++ b/src/gridtools/HistogramOnGrid.h @@ -47,11 +47,11 @@ public: void calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const ; void finish( const std::vector<double>& buffer ); virtual void accumulate( const unsigned& ipoint, const double& weight, const double& dens, const std::vector<double>& der, std::vector<double>& buffer ) const ; - virtual double getGridElement( const unsigned& ipoint, const unsigned& jelement ) const ; unsigned getNumberOfBufferPoints() const ; KernelFunctions* getKernelAndNeighbors( std::vector<double>& point, unsigned& num_neigh, std::vector<unsigned>& neighbors ) const; std::vector<Value*> getVectorOfValues() const ; void addOneKernelEachTimeOnly(){ addOneKernelAtATime=true; } + bool noDiscreteKernels() const ; }; inline diff --git a/src/gridtools/InterpolateGrid.cpp b/src/gridtools/InterpolateGrid.cpp index 16c8fdc58..763799c0c 100644 --- a/src/gridtools/InterpolateGrid.cpp +++ b/src/gridtools/InterpolateGrid.cpp @@ -37,18 +37,13 @@ namespace PLMD { namespace gridtools { class InterpolateGrid : public ActionWithInputGrid { -private: - std::vector<unsigned> nbin; - std::vector<double> gspacing; public: static void registerKeywords( Keywords& keys ); explicit InterpolateGrid(const ActionOptions&ao); unsigned getNumberOfDerivatives(){ return 0; } unsigned getNumberOfQuantities() const ; - void clearGrid(); void compute( const unsigned& current, MultiValue& myvals ) const ; bool isPeriodic(){ return false; } - bool onStep() const { return true; } }; PLUMED_REGISTER_ACTION(InterpolateGrid,"INTERPOLATE_GRID") @@ -57,7 +52,7 @@ void InterpolateGrid::registerKeywords( Keywords& keys ){ ActionWithInputGrid::registerKeywords( keys ); keys.add("optional","GRID_BIN","the number of bins for the grid"); keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)"); - keys.remove("STRIDE"); keys.remove("KERNEL"); keys.remove("BANDWIDTH"); keys.remove("CLEAR"); + keys.remove("KERNEL"); keys.remove("BANDWIDTH"); } InterpolateGrid::InterpolateGrid(const ActionOptions&ao): @@ -68,16 +63,16 @@ ActionWithInputGrid(ao) if( ingrid->noDerivatives() ) error("cannot interpolate a grid that does not have derivatives"); // Create the input from the old string createGrid( "grid", "COMPONENTS=" + getLabel() + " " + ingrid->getInputString() ); - finishGridSetup(); - parseVector("GRID_BIN",nbin); parseVector("GRID_SPACING",gspacing); + std::vector<unsigned> nbin; parseVector("GRID_BIN",nbin); + std::vector<double> gspacing; parseVector("GRID_SPACING",gspacing); if( nbin.size()!=ingrid->getDimension() && gspacing.size()!=ingrid->getDimension() ){ error("GRID_BIN or GRID_SPACING must be set"); } // Need this for creation of tasks mygrid->setBounds( ingrid->getMin(), ingrid->getMax(), nbin, gspacing ); - resizeFunctions(); + setAveragingAction( mygrid, true ); // Now create task list for(unsigned i=0;i<mygrid->getNumberOfPoints();++i) addTaskToList(i); @@ -91,10 +86,6 @@ unsigned InterpolateGrid::getNumberOfQuantities() const { return 2 + ingrid->getDimension(); } -void InterpolateGrid::clearGrid(){ - mygrid->setBounds( ingrid->getMin(), ingrid->getMax(), nbin, gspacing ); mygrid->clear(); -} - void InterpolateGrid::compute( const unsigned& current, MultiValue& myvals ) const { std::vector<double> pos( mygrid->getDimension() ); mygrid->getGridPointCoordinates( current, pos ); std::vector<double> der( mygrid->getDimension() ); double val = getFunctionValueAndDerivatives( pos, der ); diff --git a/src/multicolvar/MultiColvarDensity.cpp b/src/multicolvar/MultiColvarDensity.cpp index e7eece5c2..eae18b993 100644 --- a/src/multicolvar/MultiColvarDensity.cpp +++ b/src/multicolvar/MultiColvarDensity.cpp @@ -101,8 +101,8 @@ public: unsigned getNumberOfQuantities() const ; bool isPeriodic(){ return false; } unsigned getNumberOfDerivatives(){ return 0; } - void clearGrid(); - bool prepareForTasks(); + void clearAverage(); + void prepareForAveraging(); void compute( const unsigned& , MultiValue& ) const ; }; @@ -230,7 +230,7 @@ ActionWithGrid(ao) if( mycolv->isDensity() ) createGrid( "histogram", vstring ); else createGrid( "average", vstring ); // And finish the grid setup - finishGridSetup(); + setAveragingAction( mygrid, true ); // Enusre units for cube files are set correctly if( !fractional ){ @@ -247,8 +247,7 @@ unsigned MultiColvarDensity::getNumberOfQuantities() const { return directions.size() + 2; } -void MultiColvarDensity::clearGrid(){ - plumed_assert( mygrid->wasreset() ); +void MultiColvarDensity::clearAverage(){ std::vector<double> min(directions.size()), max(directions.size()); std::vector<std::string> gmin(directions.size()), gmax(directions.size());; for(unsigned i=0;i<directions.size();++i){ min[i]=-0.5; max[i]=0.5; } @@ -267,10 +266,11 @@ void MultiColvarDensity::clearGrid(){ } } for(unsigned i=0;i<directions.size();++i){ Tools::convert(min[i],gmin[i]); Tools::convert(max[i],gmax[i]); } - mygrid->clear(); mygrid->setBounds( gmin, gmax, nbins, gspacing ); resizeFunctions(); + ActionWithAveraging::clearAverage(); + mygrid->setBounds( gmin, gmax, nbins, gspacing ); resizeFunctions(); } -bool MultiColvarDensity::prepareForTasks(){ +void MultiColvarDensity::prepareForAveraging(){ for(unsigned i=0;i<directions.size();++i){ if( confined[i] ) continue; std::string max; Tools::convert( 0.5*mycolv->getBox()(directions[i],directions[i]), max ); @@ -281,7 +281,7 @@ bool MultiColvarDensity::prepareForTasks(){ for(unsigned i=0;i<stash->getNumberOfStoredValues();++i) taskFlags[i]=1; lockContributors(); // Retrieve the origin - origin = getPosition(0); return true; + origin = getPosition(0); } void MultiColvarDensity::compute( const unsigned& current, MultiValue& myvals ) const { diff --git a/src/vesselbase/ActionWithAveraging.cpp b/src/vesselbase/ActionWithAveraging.cpp new file mode 100644 index 000000000..7a0b60340 --- /dev/null +++ b/src/vesselbase/ActionWithAveraging.cpp @@ -0,0 +1,126 @@ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Copyright (c) 2012-2016 The plumed team + (see the PEOPLE file at the root of the distribution for a list of names) + + See http://www.plumed.org for more information. + + This file is part of plumed, version 2. + + plumed is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + plumed is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with plumed. If not, see <http://www.gnu.org/licenses/>. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +#include "ActionWithAveraging.h" +#include "core/PlumedMain.h" +#include "core/ActionSet.h" + +namespace PLMD { +namespace vesselbase { + +void ActionWithAveraging::registerKeywords( Keywords& keys ){ + Action::registerKeywords( keys ); ActionPilot::registerKeywords( keys ); + ActionAtomistic::registerKeywords( keys ); ActionWithArguments::registerKeywords( keys ); ActionWithVessel::registerKeywords( keys ); + keys.add("compulsory","STRIDE","1","the frequency with which the data should be collected and added to the quantity being averaged"); + keys.add("compulsory","CLEAR","0","the frequency with which to clear all the accumulated data. The default value " + "of 0 implies that all the data will be used and that the grid will never be cleared"); + keys.add("optional","LOGWEIGHTS","list of actions that calculates log weights that should be used to weight configurations when calculating averages"); + keys.addFlag("UNORMALIZED",false,"output the unaveraged quantity/quantities."); +} + +ActionWithAveraging::ActionWithAveraging( const ActionOptions& ao ): +Action(ao), +ActionPilot(ao), +ActionAtomistic(ao), +ActionWithArguments(ao), +ActionWithVessel(ao), +myaverage(NULL), +useRunAllTasks(false), +clearstride(0) +{ + if( keywords.exists("CLEAR") ){ + parse("CLEAR",clearstride); + if( clearstride>0 ){ + if( clearstride%getStride()!=0 ) error("CLEAR parameter must be a multiple of STRIDE"); + log.printf(" clearing grid every %d steps \n",clearstride); + } + } + if( keywords.exists("LOGWEIGHTS") ){ + std::vector<std::string> wwstr; parseVector("LOGWEIGHTS",wwstr); + log.printf(" reweighting using weights from "); + std::vector<Value*> arg( getArguments() ); + for(unsigned i=0;i<wwstr.size();++i){ + ActionWithValue* val = plumed.getActionSet().selectWithLabel<ActionWithValue*>(wwstr[i]); + if( !val ) error("could not find value named"); + weights.push_back( val->copyOutput(val->getLabel()) ); + arg.push_back( val->copyOutput(val->getLabel()) ); + log.printf("%s ",wwstr[i].c_str() ); + } + log.printf("\n"); requestArguments( arg ); + } + if( keywords.exists("UNORMALIZED") ) parseFlag("UNORMALIZED",unormalised); +} + +void ActionWithAveraging::setAveragingAction( AveragingVessel* av_vessel, const bool& usetasks ){ + myaverage=av_vessel; addVessel( myaverage ); + useRunAllTasks=usetasks; resizeFunctions(); +} + +void ActionWithAveraging::lockRequests(){ + ActionAtomistic::lockRequests(); + ActionWithArguments::lockRequests(); +} + +void ActionWithAveraging::unlockRequests(){ + ActionAtomistic::unlockRequests(); + ActionWithArguments::unlockRequests(); +} + +void ActionWithAveraging::calculateNumericalDerivatives(PLMD::ActionWithValue*){ + error("not possible to compute numerical derivatives for this action"); +} + +void ActionWithAveraging::update(){ + if( getStep()==0 || !onStep() ) return; + // Clear if it is time to reset + if( myaverage ){ + if( myaverage->wasreset() ) clearAverage(); + } + // Calculate the weight for all reweighting + if ( weights.size()>0 ){ + double sum=0; for(unsigned i=0;i<weights.size();++i) sum+=weights[i]->get(); + cweight = exp( sum ); + } else { + cweight=1.0; + } + // Prepare to do the averaging + prepareForAveraging(); + // Run all the tasks (if required + if( useRunAllTasks ) runAllTasks(); + // This the averaging if it is not done using task list + else performOperations( true ); + // Update the norm + if( myaverage ) myaverage->setNorm( cweight + myaverage->getNorm() ); + // Finish the averaging + finishAveraging(); + // By resetting here we are ensuring that the grid will be cleared at the start of the next step + if( myaverage ){ + if( getStride()==0 || (clearstride>0 && getStep()%clearstride==0) ) myaverage->reset(); + } +} + +void ActionWithAveraging::clearAverage(){ plumed_assert( myaverage->wasreset() ); myaverage->clear(); } + +void ActionWithAveraging::performOperations( const bool& from_update ){ plumed_error(); } + + +} +} diff --git a/src/vesselbase/ActionWithAveraging.h b/src/vesselbase/ActionWithAveraging.h new file mode 100644 index 000000000..7642bcd17 --- /dev/null +++ b/src/vesselbase/ActionWithAveraging.h @@ -0,0 +1,94 @@ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Copyright (c) 2012-2016 The plumed team + (see the PEOPLE file at the root of the distribution for a list of names) + + See http://www.plumed.org for more information. + + This file is part of plumed, version 2. + + plumed is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + plumed is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with plumed. If not, see <http://www.gnu.org/licenses/>. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +#ifndef __PLUMED_vesselbase_ActionWithAveraging_h +#define __PLUMED_vesselbase_ActionWithAveraging_h + +#include "core/ActionPilot.h" +#include "core/ActionWithValue.h" +#include "core/ActionAtomistic.h" +#include "core/ActionWithArguments.h" +#include "ActionWithVessel.h" +#include "AveragingVessel.h" + +namespace PLMD { +namespace vesselbase { + +/** +\ingroup INHERIT +This abstract base class should be used if you are writing some method that calculates an "average" from a set of +trajectory frames. Notice that we use the word average very broadly here and state that even dimensionality +reduction algorithms calculate an "average." In other words, what we mean by average is that the method is going +to take in data from each trajectory frame and only calculate the final quantity once a certain amount of data has +been collected. +*/ + +class ActionWithAveraging : + public ActionPilot, + public ActionAtomistic, + public ActionWithArguments, + public ActionWithVessel +{ +friend class AveragingVessel; +private: +/// The vessel which is used to compute averages + AveragingVessel* myaverage; +/// This ensures runAllTasks is used + bool useRunAllTasks; +/// The frequency with which to clear the grid + unsigned clearstride; +/// The weights we are going to use for reweighting + std::vector<Value*> weights; +/// Are we accumulated the unormalized quantity + bool unormalised; +protected: +/// The current weight + double cweight; +/// Set the averaging action + void setAveragingAction( AveragingVessel* av_vessel, const bool& usetasks ); +public: + static void registerKeywords( Keywords& keys ); + explicit ActionWithAveraging( const ActionOptions& ); + void lockRequests(); + void unlockRequests(); + void calculateNumericalDerivatives(PLMD::ActionWithValue*); + unsigned getNumberOfArguments() const ; + void calculate(){} + void apply(){} + void update(); +/// This does the clearing of the action + virtual void clearAverage(); +/// This is done before the averaging comences + virtual void prepareForAveraging(){} +/// This does the averaging operation + virtual void performOperations( const bool& from_update ); +/// This is done once the averaging is finished + virtual void finishAveraging(){} +}; + +inline +unsigned ActionWithAveraging::getNumberOfArguments() const { + return ActionWithArguments::getNumberOfArguments() - weights.size(); +} + +} +} +#endif diff --git a/src/vesselbase/ActionWithVessel.cpp b/src/vesselbase/ActionWithVessel.cpp index 876f89757..9bf4e72b7 100644 --- a/src/vesselbase/ActionWithVessel.cpp +++ b/src/vesselbase/ActionWithVessel.cpp @@ -294,8 +294,6 @@ void ActionWithVessel::runAllTasks(){ for(unsigned i=rank;i<nactive_tasks;i+=stride){ // Calculate the stuff in the loop for this action performTask( indexOfTaskInFullList[i], partialTaskList[i], myvals ); - // Weight should be between zero and one - plumed_dbg_assert( myvals.get(0)>=0 && myvals.get(0)<=1.0 ); // Check for conditions that allow us to just to skip the calculation // the condition is that the weight of the contribution is low diff --git a/src/vesselbase/AveragingVessel.cpp b/src/vesselbase/AveragingVessel.cpp new file mode 100644 index 000000000..7d8933bd6 --- /dev/null +++ b/src/vesselbase/AveragingVessel.cpp @@ -0,0 +1,62 @@ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Copyright (c) 2012-2016 The plumed team + (see the PEOPLE file at the root of the distribution for a list of names) + + See http://www.plumed.org for more information. + + This file is part of plumed, version 2. + + plumed is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + plumed is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with plumed. If not, see <http://www.gnu.org/licenses/>. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +#include "AveragingVessel.h" +#include "ActionWithAveraging.h" + +namespace PLMD { +namespace vesselbase { + +void AveragingVessel::registerKeywords( Keywords& keys ){ + Vessel::registerKeywords( keys ); +} + +AveragingVessel::AveragingVessel( const vesselbase::VesselOptions& vo ): +Vessel(vo), +wascleared(true) +{ + ActionWithAveraging* myav = dynamic_cast<ActionWithAveraging*>( getAction() ); + plumed_assert( myav ); unormalised = myav->unormalised; +} + +void AveragingVessel::finish( const std::vector<double>& buffer ){ + wascleared=false; for(unsigned i=1;i<data.size();++i) data[i]+=buffer[bufstart + i - 1]; +} + +bool AveragingVessel::wasreset() const { + return wascleared; +} + +void AveragingVessel::clear(){ + plumed_assert( wascleared ); data.assign( data.size(), 0.0 ); +} + +void AveragingVessel::reset(){ + wascleared=true; +} + +void AveragingVessel::setDataSize( const unsigned& size ){ + if( data.size()!=(1+size) ) data.resize( 1+size, 0 ); +} + +} +} + diff --git a/src/vesselbase/AveragingVessel.h b/src/vesselbase/AveragingVessel.h new file mode 100644 index 000000000..c71427f93 --- /dev/null +++ b/src/vesselbase/AveragingVessel.h @@ -0,0 +1,101 @@ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Copyright (c) 2012-2016 The plumed team + (see the PEOPLE file at the root of the distribution for a list of names) + + See http://www.plumed.org for more information. + + This file is part of plumed, version 2. + + plumed is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + plumed is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with plumed. If not, see <http://www.gnu.org/licenses/>. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +#ifndef __PLUMED_vesselbase_AveragingVessel_h +#define __PLUMED_vesselbase_AveragingVessel_h + +#include "Vessel.h" + +namespace PLMD { +namespace vesselbase { + +class AveragingVessel : public Vessel { +private: +/// The grid was recently cleared and bounds can be set + bool wascleared; +/// Are we outputting unormalised data + bool unormalised; +/// The data that is being averaged + std::vector<double> data; +protected: +/// Set the size of the data vector + void setDataSize( const unsigned& size ); +/// Set an element of the data array + void setDataElement( const unsigned& myelem, const double& value ); +/// Add some value to an element of the data array + void addDataElement( const unsigned& myelem, const double& value ); +/// Get the value of one of the data element + double getDataElement( const unsigned& myelem ) const ; +/// Are we averaging the data + bool noAverage() const { return unormalised; } +public: +/// keywords + static void registerKeywords( Keywords& keys ); +/// Constructor + explicit AveragingVessel( const vesselbase::VesselOptions& ); +/// Copy data from an accumulated buffer into the grid + virtual void finish( const std::vector<double>& ); +/// Was the grid cleared on the last step + bool wasreset() const ; +/// Clear all the data stored on the grid + virtual void clear(); +/// Reset the grid so that it is cleared at start of next time it is calculated + virtual void reset(); +/// Functions for dealing with normalisation constant + void setNorm( const double& snorm ); + double getNorm() const ; + bool applyForce( std::vector<double>& forces ){ return false; } +}; + +inline +void AveragingVessel::setDataElement( const unsigned& myelem, const double& value ){ + plumed_dbg_assert( myelem<1+data.size() ); + wascleared=false; data[1+myelem]=value; +} + +inline +void AveragingVessel::addDataElement( const unsigned& myelem, const double& value ){ + plumed_dbg_assert( myelem<1+data.size() ); + wascleared=false; data[1+myelem]+=value; +} + +inline +double AveragingVessel::getDataElement( const unsigned& myelem ) const { + plumed_dbg_assert( myelem<data.size()-1 ); + if( unormalised ) return data[1+myelem]; + return data[1+myelem] / data[0]; +} + +inline +void AveragingVessel::setNorm( const double& snorm ){ + plumed_dbg_assert( data.size()>0 ); + data[0]=snorm; +} + +inline +double AveragingVessel::getNorm() const { + plumed_dbg_assert( data.size()>0 ); + return data[0]; +} + +} +} +#endif -- GitLab