package etomica.data.meter;
import etomica.EtomicaInfo;
import etomica.Phase;
import etomica.Space;
import etomica.data.DataSourceScalar;
import etomica.space.Tensor;
import etomica.units.Dimension;

/**
 * This is a meter to measure the surface tension for a hard potential.  
 * It uses the meter that measures the pressure tensor to do this
 * and returns the result as PV/N, which has dimensions of energy.
 * Assumes a slab geometry for the liquid, so surface tension is divided by 2 to account for both interfaces.
 *
 * @author Rob Riggleman
 */

public class MeterSurfaceTensionHard extends DataSourceScalar {//, EtomicaElement {
    private final Tensor pressureTensor;
    private final MeterTensorVelocity velocityTensor;
    private final MeterTensorVirialHard virialTensor;
    private double surfaceTension, collisionValue, velocityValue;
    private int D;
    
    public MeterSurfaceTensionHard(Space space) {
        super();
        velocityTensor = new MeterTensorVelocity(space);
        virialTensor = new MeterTensorVirialHard(space);
        pressureTensor = space.makeTensor();
        D = space.D();
        setLabel("Surface Tension");
    }
    
    public static EtomicaInfo getEtomicaInfo() {
        EtomicaInfo info = new EtomicaInfo("Measures surface tension for a collision-based potential");
        return info;
    }

    /**
     * Returns dimensions of this meters measured quanitity, which in this case is energy
     */
    public final Dimension getDimension() {return Dimension.ENERGY;}
    
    /**
     * Gives current value of the surface tension, obtained by summing velocity and virial contributions.
     * Virial contribution includes sum over all collisions since last call to this method, while
     * velocity contribution is based on atom velocities in current configuration.
     * Surface tension is given by difference between normal and tangential stress components.
     * Written for 2-, or 3-dimensional systems; assumes that normal to interface is along x-axis.
     */
    
    public double getDataAsScalar(Phase p) {
        if (phase == null) throw new IllegalStateException("must call setPhase before using meter");
        pressureTensor.E(velocityTensor.getDataAsTensor(p));
        pressureTensor.PE(virialTensor.getDataAsTensor(p));
        if (D == 1) {surfaceTension = pressureTensor.component(0, 0);}
        else if (D == 2) {surfaceTension = 0.5*(pressureTensor.component(0, 0) - pressureTensor.component(1, 1));}
        else {surfaceTension = 0.5*(pressureTensor.component(0, 0) - 0.5*(pressureTensor.component(1, 1) + pressureTensor.component(2, 2)));}
        return surfaceTension;
    }
    
}

@@ -36,27 +36,74 @@
 etomica.
-EtomicaInfo
+DataInfo;%0Aimport etomica.EtomicaInfo;%0Aimport etomica.Meter
 ;%0Aimport
@@ -656,16 +656,33 @@
 eScalar 
+implements Meter 
 %7B//, Eto
@@ -694,246 +694,12 @@
 leme
-nt %7B%0A    private final Tensor pressureTensor;%0A    private final MeterTensorVelocity velocityTensor;%0A    private final MeterTensorVirialHard virialTensor;%0A    private double surfaceTension, collisionValue, velocityValue;%0A    private i
 nt 
-D;
+%7B
 %0A   
@@ -764,16 +764,64 @@
   super(
+new DataInfo(%22Surface Tension%22,Dimension.ENERGY)
 );%0A     
@@ -978,68 +978,8 @@
 ();%0A
-        D = space.D();%0A        setLabel(%22Surface Tension%22);%0A
     
@@ -1886,15 +1886,8 @@
 lar(
-Phase p
 ) %7B%0A
@@ -2036,32 +2036,36 @@
 etDataAsTensor(p
+hase
 ));%0A        pres
@@ -2108,16 +2108,20 @@
 Tensor(p
+hase
 ));%0A    
@@ -2128,21 +2128,71 @@
     
-if (D == 1) %7B
+switch (phase.space().D) %7B%0A            case 1:%0A                
 surf
@@ -2235,26 +2235,31 @@
 t(0, 0);
-%7D
 %0A
+      
         
 else if 
@@ -2254,26 +2254,53 @@
     
-else if (D == 2) %7B
+  break;%0A            case 2:%0A                
 surf
@@ -2382,26 +2382,31 @@
 (1, 1));
-%7D
 %0A
+      
         
 else %7Bsu
@@ -2401,14 +2401,53 @@
     
-else %7B
+  break;%0A            case 3:%0A                
 surf
@@ -2568,16 +2568,48 @@
 2, 2)));
+%0A                break;%0A        
 %7D%0A      
@@ -2644,10 +2644,595 @@
  %7D%0A    %0A
+    /**%0A     * @return Returns the phase.%0A     */%0A    public Phase getPhase() %7B%0A        return phase;%0A    %7D%0A    /**%0A     * @param phase The phase to set.%0A     */%0A    public void setPhase(Phase phase) %7B%0A        if (phase.space().D %3C 1 %7C%7C phase.space().D %3E 3) throw new IllegalArgumentException(%22phase's space must be 1, 2 or 3 dimensional%22);%0A        this.phase = phase;%0A    %7D%0A%0A    private Phase phase;%0A    private final Tensor pressureTensor;%0A    private final MeterTensorVelocity velocityTensor;%0A    private final MeterTensorVirialHard virialTensor;%0A    private double surfaceTension;%0A
 %7D%0A

update for Data changes