Repository: devitocodes/devito
Issue: norm broken due to loss of accuracy

reproducer:

```
+        grid = Grid(shape=(401, 301, 181))
+
+        f = Function(name='f', grid=grid)
+
+        f.data[:] = 1.0
+        from IPython import embed; embed()
+
+        assert np.isclose(norm(f1),
+                          switchconfig(openmp=True)(norm)(f),
+                          rtol=1e-5)
```

enforcing accumulation on a `double`  scalar should fix it

Changed files:
tests/test_builtins.py, devito/ir/clusters/cluster.py, devito/builtins/arithmetic.py

diff --git a/devito/builtins/arithmetic.py b/devito/builtins/arithmetic.py
index beb7cdd4e..122218bac 100644
--- a/devito/builtins/arithmetic.py
+++ b/devito/builtins/arithmetic.py
@@ -28,7 +28,7 @@ def norm(f, order=2):
     # otherwise we would eventually be summing more than expected
     p, eqns = f.guard() if f.is_SparseFunction else (f, [])
 
-    s = dv.types.Symbol(name='sum', dtype=f.dtype)
+    s = dv.types.Symbol(name='sum', dtype=np.float64)
 
     with MPIReduction(f) as mr:
         op = dv.Operator([dv.Eq(s, 0.0)] +
diff --git a/devito/ir/clusters/cluster.py b/devito/ir/clusters/cluster.py
index 7c7514713..973858b9a 100644
--- a/devito/ir/clusters/cluster.py
+++ b/devito/ir/clusters/cluster.py
@@ -217,14 +217,13 @@ class Cluster(object):
         floating point arithmetic, then the expressions performing integer
         arithmetic are ignored, assuming that they are only carrying out array
         index calculations. If two expressions perform floating point
-        calculations with mixed precision, the data type with highest precision
-        is returned.
+        calculations with different precision, the data type with highest
+        precision is returned.
         """
         dtypes = {i.dtype for i in self.exprs}
         fdtypes = {i for i in dtypes if np.issubdtype(i, np.floating)}
         if len(fdtypes) > 1:
-            raise NotImplementedError("Unsupported Cluster with mixed floating "
-                                      "point arithmetic %s" % str(fdtypes))
+            return max(fdtypes, key=lambda i: np.dtype(i).itemsize)
         elif len(fdtypes) == 1:
             return fdtypes.pop()
         elif len(dtypes) == 1:
@@ -396,14 +395,13 @@ class ClusterGroup(tuple):
         The arithmetic data type of this ClusterGroup. If at least one
         Cluster performs floating point arithmetic, then Clusters performing
         integer arithmetic are ignored. If two Clusters perform floating
-        point calculations with different precision, return the data type with
-        highest precision.
+        point calculations with different precision, the data type with highest
+        precision is returned.
         """
         dtypes = {i.dtype for i in self}
         fdtypes = {i for i in dtypes if np.issubdtype(i, np.floating)}
         if len(fdtypes) > 1:
-            raise NotImplementedError("Unsupported ClusterGroup with mixed floating "
-                                      "point arithmetic %s" % str(fdtypes))
+            return max(fdtypes, key=lambda i: np.dtype(i).itemsize)
         elif len(fdtypes) == 1:
             return fdtypes.pop()
         elif len(dtypes) == 1:
diff --git a/tests/test_builtins.py b/tests/test_builtins.py
index fc1653611..418d0d544 100644
--- a/tests/test_builtins.py
+++ b/tests/test_builtins.py
@@ -369,3 +369,14 @@ class TestBuiltinsResult(object):
         term1 = np.max(rec0.data)
         term2 = mmax(rec0)
         assert np.isclose(term1/term2 - 1, 0.0, rtol=0.0, atol=1e-5)
+
+    def test_issue_1860(self):
+        grid = Grid(shape=(401, 301, 181))
+
+        f = Function(name='f', grid=grid)
+
+        f.data[:] = 1.0
+
+        assert np.isclose(norm(f),
+                          switchconfig(language='openmp')(norm)(f),
+                          rtol=1e-5)