/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package etomica.simulation;

import etomica.config.Configuration;
import etomica.config.ConfigurationResourceFile;
import etomica.data.AccumulatorAverage;
import etomica.data.AccumulatorAverageFixed;
import etomica.data.DataPumpListener;
import etomica.data.meter.MeterPotentialEnergyFromIntegrator;
import etomica.data.meter.MeterPressureHard;
import etomica.space3d.Space3D;
import etomica.tests.TestSWChain;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

import java.util.concurrent.TimeUnit;

@State(Scope.Benchmark)
@Fork(1)
public class BenchSimSWChain {

    @Param({"500", "4000"})
    public int numMolecules;

    @Param({"100000"})
    public int numSteps;

    private TestSWChain sim;
    private MeterPressureHard pMeter;

    @Setup(Level.Iteration)
    public void setUp() {
        double simTime = numSteps / numMolecules;
        Configuration config = new ConfigurationResourceFile(
                String.format("SWChain%d.pos", numMolecules),
                TestSWChain.class
        );

        sim = new TestSWChain(Space3D.getInstance(), numMolecules, simTime, config);

        pMeter = new MeterPressureHard(sim.integrator);
        MeterPotentialEnergyFromIntegrator energyMeter = new MeterPotentialEnergyFromIntegrator(sim.integrator);
        AccumulatorAverage energyAccumulator = new AccumulatorAverageFixed();
        DataPumpListener energyPump = new DataPumpListener(energyMeter, energyAccumulator);
        energyAccumulator.setBlockSize(50);
        sim.integrator.getEventManager().addListener(energyPump);
        sim.integrator.reset();
    }

    @Benchmark
    @BenchmarkMode(Mode.Throughput)
    @OutputTimeUnit(TimeUnit.SECONDS)
    @Warmup(time = 3, iterations = 3)
    @Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS)
    public long integratorStep() {
        sim.integrator.doStep();
        return sim.integrator.getStepCount();
    }

    public static void main(String[] args) throws RunnerException {
        Options opts = new OptionsBuilder()
                .include(BenchSimSWChain.class.getSimpleName())
                .build();

        new Runner(opts).run();
    }
}

@@ -531,27 +531,150 @@
 r.MeterP
-ressureHard
+otentialEnergyFromIntegratorFasterer;%0Aimport etomica.data.meter.MeterPressureHard;%0Aimport etomica.data.meter.MeterPressureHardFasterer
 ;%0Aimport
@@ -733,16 +733,54 @@
 WChain;%0A
+import etomica.tests.TestSWChainSlow;%0A
 import o
@@ -1252,32 +1252,31 @@
 ate 
-MeterPressureHard pMeter
+TestSWChainSlow simSlow
 ;%0A%0A 
@@ -1556,19 +1556,37 @@
         
-sim
+%7B%0A            simSlow
  = new T
@@ -1595,16 +1595,20 @@
 tSWChain
+Slow
 (Space3D
@@ -1641,17 +1641,8 @@
 es, 
-simTime, 
 conf
@@ -1654,16 +1654,691 @@
 %0A       
+     MeterPressureHard pMeter = new MeterPressureHard(simSlow.integrator);%0A            MeterPotentialEnergyFromIntegrator energyMeter = new MeterPotentialEnergyFromIntegrator(simSlow.integrator);%0A            AccumulatorAverage energyAccumulator = new AccumulatorAverageFixed();%0A            DataPumpListener energyPump = new DataPumpListener(energyMeter, energyAccumulator);%0A            energyAccumulator.setBlockSize(50);%0A            simSlow.integrator.getEventManager().addListener(energyPump);%0A            simSlow.integrator.reset();%0A        %7D%0A%0A        %7B%0A            sim = new TestSWChain(Space3D.getInstance(), numMolecules, config);%0A%0A            MeterPressureHardFasterer
  pMeter 
@@ -2356,24 +2356,32 @@
 PressureHard
+Fasterer
 (sim.integra
@@ -2378,32 +2378,36 @@
 im.integrator);%0A
+    
         MeterPot
@@ -2424,32 +2424,40 @@
 gyFromIntegrator
+Fasterer
  energyMeter = n
@@ -2489,24 +2489,32 @@
 omIntegrator
+Fasterer
 (sim.integra
@@ -2519,32 +2519,36 @@
 rator);%0A        
+ 
+   
 AccumulatorAvera
@@ -2593,32 +2593,36 @@
 AverageFixed();%0A
+    
         DataPump
@@ -2697,32 +2697,36 @@
 lator);%0A        
+ 
+   
 energyAccumulato
@@ -2737,32 +2737,36 @@
 tBlockSize(50);%0A
+    
         sim.inte
@@ -2815,32 +2815,36 @@
 yPump);%0A        
+    
 sim.integrator.r
@@ -2847,24 +2847,366 @@
 or.reset();%0A
+        %7D%0A    %7D%0A%0A    @Benchmark%0A    @BenchmarkMode(Mode.Throughput)%0A    @OutputTimeUnit(TimeUnit.SECONDS)%0A    @Warmup(time = 3, iterations = 3)%0A    @Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS)%0A    public long integratorStepSlow() %7B%0A        simSlow.integrator.doStep();%0A        return simSlow.integrator.getStepCount();%0A
     %7D%0A%0A    @

fix SWCHain benchmark