Index: /inundation/pyvolution/quantity.py
===================================================================
--- /inundation/pyvolution/quantity.py	(revision 1753)
+++ /inundation/pyvolution/quantity.py	(revision 1754)
@@ -54,6 +54,69 @@
         self.interpolate()
 
+
+
+    #Methods for operator overloading    
     def __len__(self):
         return self.centroid_values.shape[0]
+
+
+    def __neg__(self):
+        """Negate all values in this quantity giving meaning to the
+        expression -Q where Q is an instance of class Quantity
+        """
+
+        Q = Quantity(self.domain)
+        Q.set_values(-self.vertex_values)
+        return Q
+    
+
+    def __add__(self, other):
+        """Add to self anything that could populate a quantity:
+        E.g other can be a constant, an array, a function, another quantity
+        (except for a filename or points, attributes (for now))
+        - see set_values for details
+        """
+
+        Q = Quantity(self.domain)
+        Q.set_values(other)        
+
+        result = Quantity(self.domain)
+        result.set_values(self.vertex_values + Q.vertex_values)
+        return result
+
+    def __radd__(self, other):
+        """Handle cases like 7+Q, where Q is an instance of class Quantity
+        """
+        return self + other
+    
+    
+    def __sub__(self, other):    
+        return self + -other  #Invoke __neg__
+
+    def __mul__(self, other):
+        """Multiply self with anything that could populate a quantity:
+        E.g other can be a constant, an array, a function, another quantity
+        (except for a filename or points, attributes (for now))
+        - see set_values for details
+
+        Note that if two quantitites q1 and q2 are multiplied,
+        vertex values are multiplied entry by entry
+        while centroid and edge values are re-interpolated.
+        Hence they won't be the product of centroid or edge values
+        from q1 and q2.
+        """
+
+        Q = Quantity(self.domain)
+        Q.set_values(other)
+        
+        result = Quantity(self.domain)
+        result.set_values(self.vertex_values * Q.vertex_values)
+        return result
+        
+    def __rmul__(self, other):
+        """Handle cases like 3*Q, where Q is an instance of class Quantity
+        """
+        return self * other
+    
 
     def interpolate(self):
@@ -97,11 +160,9 @@
         
         numeric:
-        
           Compatible list, Numeric array (see below) or constant.
-          If callable it will treated as a function for convenience and
-          backwards compatibility
+          If callable it will treated as a function 
+          If instance of another Quantity it will be treated as such.
 
         quantity:
-
           Another quantity (compatible quantity, e.g. obtained as a
           linear combination of quantities)
@@ -124,5 +185,5 @@
           If attribute_name is specified, any array matching that name
           will be used. Otherwise the first available one will be used.
-          
+
         alpha:
           Smoothing parameter to be used with least squares fits.
@@ -173,9 +234,8 @@
 
         #General input checks
+        L = [numeric, quantity, function, points, filename]        
         msg = 'Exactly one of the arguments '+\
               'numeric, quantity, function, points, or filename '+\
-              'must be present.'
-        L = [numeric, quantity, function, points, filename]
-
+              'must be present. L = %s' %str(L)
         assert L.count(None) == len(L)-1, msg
 
@@ -204,7 +264,11 @@
                 self.set_values_from_function(numeric,
                                               location, indices, verbose)
+            elif isinstance(numeric, Quantity):
+                self.set_values_from_quantity(numeric,
+                                              location, indices, verbose)
             else:
                 msg = 'Illegal type for argument numeric: %s' %str(numeric)
                 raise msg
+            
         elif quantity is not None:
             self.set_values_from_quantity(quantity,
@@ -302,5 +366,5 @@
         location: Where values are to be stored.
         Permissible options are: vertices, edges, centroid, unique vertices
-        Default is "vertices"
+        Default is 'vertices'
 
         indices - if this action is carried out on a subset of
@@ -396,8 +460,21 @@
                                  location, indices, verbose):
         """Set quantity values from specified quantity instance q
-        """
-
-
-        raise 'not yet implemented'
+
+        Location is ignored 
+        """
+        
+        
+        A = q.vertex_values
+
+        from Numeric import allclose
+        msg = 'Quantities are defined on different meshes. '+\
+              'This might be a case for implementing interpolation '+\
+              'between different meshes.'
+        assert allclose(A.shape, self.vertex_values.shape), msg
+
+        self.set_values(A, location='vertices',
+                        indices=indices,
+                        verbose=verbose)
+
 
     def set_values_from_function(self, f,
Index: /inundation/pyvolution/test_quantity.py
===================================================================
--- /inundation/pyvolution/test_quantity.py	(revision 1753)
+++ /inundation/pyvolution/test_quantity.py	(revision 1754)
@@ -278,5 +278,5 @@
         
 
-    def test_set_vertex_values_using_least_squares(self):
+    def test_set_values_using_least_squares(self):
 
         
@@ -379,4 +379,148 @@
         
 
+
+    def test_set_values_from_quantity(self):
+
+        quantity1 = Quantity(self.mesh4)
+        quantity1.set_vertex_values([0,1,2,3,4,5])
+
+        assert allclose(quantity1.vertex_values,
+                        [[1,0,2], [1,2,4], [4,2,5], [3,1,4]])
+
+        
+        quantity2 = Quantity(self.mesh4)
+        quantity2.set_values(quantity = quantity1)
+        assert allclose(quantity2.vertex_values,
+                        [[1,0,2], [1,2,4], [4,2,5], [3,1,4]])
+
+        quantity2.set_values(quantity = 2*quantity1)
+        assert allclose(quantity2.vertex_values,
+                        [[2,0,4], [2,4,8], [8,4,10], [6,2,8]])
+        
+        quantity2.set_values(quantity = 2*quantity1 + 3)
+        assert allclose(quantity2.vertex_values,
+                        [[5,3,7], [5,7,11], [11,7,13], [9,5,11]])
+
+
+        #Check detection of quantity as first orgument
+        quantity2.set_values(2*quantity1 + 3)
+        assert allclose(quantity2.vertex_values,
+                        [[5,3,7], [5,7,11], [11,7,13], [9,5,11]])             
+
+
+
+
+
+    def test_overloading(self):
+
+        quantity1 = Quantity(self.mesh4)
+        quantity1.set_vertex_values([0,1,2,3,4,5])
+
+        assert allclose(quantity1.vertex_values,
+                        [[1,0,2], [1,2,4], [4,2,5], [3,1,4]])
+
+        
+        quantity2 = Quantity(self.mesh4)
+        quantity2.set_values([[1,2,3], [5,5,5], [0,0,9], [-6, 3, 3]],
+                             location = 'vertices')
+
+
+
+        quantity3 = Quantity(self.mesh4)
+        quantity3.set_values([[2,2,2], [7,8,9], [7,6,3], [3, 8, -8]],
+                             location = 'vertices')        
+
+
+        #Negation
+        Q = -quantity1
+        assert allclose(Q.vertex_values, -quantity1.vertex_values)
+        assert allclose(Q.centroid_values, -quantity1.centroid_values)
+        assert allclose(Q.edge_values, -quantity1.edge_values)                
+        
+        #Addition
+        Q = quantity1 + 7
+        assert allclose(Q.vertex_values, quantity1.vertex_values + 7)
+        assert allclose(Q.centroid_values, quantity1.centroid_values + 7)
+        assert allclose(Q.edge_values, quantity1.edge_values + 7)        
+        
+        Q = 7 + quantity1
+        assert allclose(Q.vertex_values, quantity1.vertex_values + 7)        
+        assert allclose(Q.centroid_values, quantity1.centroid_values + 7)
+        assert allclose(Q.edge_values, quantity1.edge_values + 7)        
+        
+        Q = quantity1 + quantity2
+        assert allclose(Q.vertex_values,
+                        quantity1.vertex_values + quantity2.vertex_values)
+        assert allclose(Q.centroid_values,
+                        quantity1.centroid_values + quantity2.centroid_values)
+        assert allclose(Q.edge_values,
+                        quantity1.edge_values + quantity2.edge_values)        
+        
+
+        Q = quantity1 + quantity2 - 3
+        assert allclose(Q.vertex_values,
+                        quantity1.vertex_values + quantity2.vertex_values - 3)
+
+        Q = quantity1 - quantity2
+        assert allclose(Q.vertex_values,
+                        quantity1.vertex_values - quantity2.vertex_values)    
+
+        #Scaling
+        Q = quantity1*3
+        assert allclose(Q.vertex_values, quantity1.vertex_values*3)
+        assert allclose(Q.centroid_values, quantity1.centroid_values*3)
+        assert allclose(Q.edge_values, quantity1.edge_values*3)                
+        Q = 3*quantity1
+        assert allclose(Q.vertex_values, quantity1.vertex_values*3)
+
+        #Multiplication
+        Q = quantity1 * quantity2
+        #print Q.vertex_values
+        #print Q.centroid_values
+        #print quantity1.centroid_values
+        #print quantity2.centroid_values
+        
+        assert allclose(Q.vertex_values,
+                        quantity1.vertex_values * quantity2.vertex_values)
+
+        #Linear combinations
+        Q = 4*quantity1 + 2
+        assert allclose(Q.vertex_values,
+                        4*quantity1.vertex_values + 2)
+        
+        Q = quantity1*quantity2 + 2
+        assert allclose(Q.vertex_values,
+                        quantity1.vertex_values * quantity2.vertex_values + 2)
+        
+        Q = quantity1*quantity2 + quantity3
+        assert allclose(Q.vertex_values,
+                        quantity1.vertex_values * quantity2.vertex_values +
+                        quantity3.vertex_values)        
+        Q = quantity1*quantity2 + 3*quantity3
+        assert allclose(Q.vertex_values,
+                        quantity1.vertex_values * quantity2.vertex_values +
+                        3*quantity3.vertex_values)                
+        Q = quantity1*quantity2 + 3*quantity3 + 5.0
+        assert allclose(Q.vertex_values,
+                        quantity1.vertex_values * quantity2.vertex_values +
+                        3*quantity3.vertex_values + 5)                        
+        
+        Q = quantity1*quantity2 - quantity3
+        assert allclose(Q.vertex_values,
+                        quantity1.vertex_values * quantity2.vertex_values -
+                        quantity3.vertex_values)                                
+        Q = 1.5*quantity1*quantity2 - 3*quantity3 + 5.0
+        assert allclose(Q.vertex_values,
+                        1.5*quantity1.vertex_values * quantity2.vertex_values -
+                        3*quantity3.vertex_values + 5)                                
+
+        #Try combining quantities and arrays and scalars
+        Q = 1.5*quantity1*quantity2.vertex_values -\
+            3*quantity3.vertex_values + 5.0 
+        assert allclose(Q.vertex_values,
+                        1.5*quantity1.vertex_values * quantity2.vertex_values -
+                        3*quantity3.vertex_values + 5)                                        
+        
+    
 
     def test_gradient(self):
