From ba842990c16f81cc734883e28726942c4748bd2f Mon Sep 17 00:00:00 2001
From: Chloe Mimeau <Chloe.Mimeau@imag.fr>
Date: Tue, 28 May 2013 13:48:20 +0000
Subject: [PATCH] Update arrays operations in stretching time integration +
 momentally fix origin problem in printer

---
 HySoP/hysop/numerics/differentialOperator.py  | 67 ++++++++++++++-----
 HySoP/hysop/numerics/fct2op.py                |  4 +-
 HySoP/hysop/numerics/integrators/euler.py     | 10 ++-
 .../numerics/integrators/runge_kutta2.py      | 22 ++++--
 .../numerics/integrators/runge_kutta3.py      | 32 ++++++---
 .../numerics/integrators/runge_kutta4.py      | 39 ++++++++---
 HySoP/hysop/operator/discrete/stretching.py   | 21 +++---
 HySoP/hysop/operator/monitors/printer.py      |  3 +-
 8 files changed, 141 insertions(+), 57 deletions(-)

diff --git a/HySoP/hysop/numerics/differentialOperator.py b/HySoP/hysop/numerics/differentialOperator.py
index 9fc8b2fa9..9c8fca832 100755
--- a/HySoP/hysop/numerics/differentialOperator.py
+++ b/HySoP/hysop/numerics/differentialOperator.py
@@ -5,7 +5,7 @@ Discrete stretching representation
 """
 from parmepy.constants import np, PARMES_REAL, ORDER
 from parmepy.numerics.method import NumMethod
-#from parmepy.tools.cpu_data_transfer import Synchronize
+from parmepy.tools.cpu_data_transfer import Synchronize
 
 
 class DifferentialOperator(NumMethod):
@@ -20,8 +20,8 @@ class DifferentialOperator(NumMethod):
         Create a Stretching operator on a given continuous domain.
         Work on a given field2 and field1 to compute the stretching term.
 
-        @param field1 : field n°1 (vorticity).
-        @param field2 : field n°2 (velocity or density).
+        @param field1 : field n1 (vorticity).
+        @param field2 : field n2 (velocity or density).
         @param method : name and order of the spacial discretization method.
         @param choice : differential operator to discretize
         """
@@ -31,7 +31,7 @@ class DifferentialOperator(NumMethod):
         self.choice = choice
         self.method = method
         self.compute_time = 0.
-        self.topology = self.field2.topology
+        self.topology = self.field1.topology
         self.meshSize = self.topology.mesh.space_step
 
 #    def setUp(self):
@@ -271,14 +271,14 @@ class DifferentialOperator(NumMethod):
         elif self.choice.find('gradV') >= 0:
 
             # Ghosts synchronization
-#            OpSynchronize = Synchronize(self.topology)
-#            OpSynchronize.apply(self.field2)
+            OpSynchronize = Synchronize(self.topology)
+            OpSynchronize.apply(self.field2)
 
             if self.method.find('FD_order2') >= 0:
                 raise ValueError("2nd order scheme Not yet implemented")
 
             else:
-                maxgersh = np.zeros(2, dtype=PARMES_REAL, order=ORDER)
+                maxArray = np.zeros(5, dtype=PARMES_REAL, order=ORDER)
 
 ##              Fourth order scheme
 #               X components of temp and result
@@ -292,6 +292,8 @@ class DifferentialOperator(NumMethod):
                     1.0 * self.field2[0][ind0+2, ind1a:ind1b, ind2a:ind2b]
                 ) / (12. * self.meshSize[0])
 
+                max1 = np.max(abs(temp1))
+
 #               temp2 = np.zeros(
 #                   (self.resolution), dtype=PARMES_REAL, order=ORDER)
                 temp2 = self.field2[0][...] * 0.
@@ -302,6 +304,8 @@ class DifferentialOperator(NumMethod):
                     1.0 * self.field2[0][ind0a:ind0b, ind1+2, ind2a:ind2b]
                 ) / (12. * self.meshSize[1])
 
+                max2 = np.max(abs(temp2))
+
 #               temp3 = np.zeros(
 #                   (self.resolution), dtype=PARMES_REAL, order=ORDER)
                 temp3 = self.field2[0][...] * 0.
@@ -314,6 +318,7 @@ class DifferentialOperator(NumMethod):
 
                 maxstr1 = np.max(abs(temp1) + abs(temp2) + abs(temp3))
                 maxadv1 = np.max(abs(temp1))
+                max3 = np.max(abs(temp3))
 
 #               Y components of temp and result
 #               temp4 = np.zeros(
@@ -326,6 +331,8 @@ class DifferentialOperator(NumMethod):
                     1.0 * self.field2[1][ind0+2, ind1a:ind1b, ind2a:ind2b]
                 ) / (12. * self.meshSize[0])
 
+                max4 = np.max(abs(temp4))
+
 #               temp5 = np.zeros(
 #                   (self.resolution), dtype=PARMES_REAL, order=ORDER)
                 temp5 = self.field2[1][...] * 0.
@@ -336,6 +343,8 @@ class DifferentialOperator(NumMethod):
                     1.0 * self.field2[1][ind0a:ind0b, ind1+2, ind2a:ind2b]
                 ) / (12. * self.meshSize[1])
 
+                max5 = np.max(abs(temp5))
+
 #               temp6 = np.zeros(
 #                   (self.resolution), dtype=PARMES_REAL, order=ORDER)
                 temp6 = self.field2[1][...] * 0.
@@ -348,6 +357,7 @@ class DifferentialOperator(NumMethod):
 
                 maxstr2 = np.max(abs(temp4)+abs(temp5)+abs(temp6))
                 maxadv2 = np.max(abs(temp5))
+                max6 = np.max(abs(temp6))
 
 #               Z components of temp and result
 #               temp7 = np.zeros(
@@ -360,6 +370,8 @@ class DifferentialOperator(NumMethod):
                     1.0 * self.field2[2][ind0+2, ind1a:ind1b, ind2a:ind2b]
                 ) / (12. * self.meshSize[0])
 
+                max7 = np.max(abs(temp7))
+
 #               temp8 = np.zeros(
 #                   (self.resolution), dtype=PARMES_REAL, order=ORDER)
                 temp8 = self.field2[2][...] * 0.
@@ -370,6 +382,8 @@ class DifferentialOperator(NumMethod):
                     1.0 * self.field2[2][ind0a:ind0b, ind1+2, ind2a:ind2b]
                 ) / (12. * self.meshSize[1])
 
+                max8 = np.max(abs(temp8))
+
 #               temp9 = np.zeros(
 #                   (self.resolution), dtype=PARMES_REAL, order=ORDER)
                 temp9 = self.field2[2][...] * 0.
@@ -382,21 +396,40 @@ class DifferentialOperator(NumMethod):
 
                 maxstr3 = np.max(abs(temp7)+abs(temp8)+abs(temp9))
                 maxadv3 = np.max(abs(temp9))
-                maxgersh[0] = max(maxstr1, maxstr2, maxstr3)
-                maxgersh[1] = max(maxadv1, maxadv2, maxadv3)
+                max9 = np.max(abs(temp9))
+
+                # grad(V) result
                 result = np.concatenate((
                     np.array([temp1, temp2, temp3]),
                     np.array([temp4, temp5, temp6]),
                     np.array([temp7, temp8, temp9])
                 ))
-
-            return result, maxgersh
+                # div(V) result
+                divergence = np.array(temp1 + temp5 + temp9)
+
+                maxdiv = np.max(abs(divergence))
+                maxMax = max(max1, max2, max3,
+                             max4, max5, max6,
+                             max7, max8, max9)
+                maxproj = maxdiv / maxMax
+
+                # maxima of partial derivatives : needed for stab conditions
+                    # advection stab
+                maxArray[0] = max(maxstr1, maxstr2, maxstr3)
+                    # stretching stab
+                maxArray[1] = max(maxadv1, maxadv2, maxadv3)
+                    # solenoidal reprojection criterion
+                maxArray[2] = maxproj
+                maxArray[3] = maxdiv
+                maxArray[4] = maxMax
+
+            return result, maxArray, divergence
 
         elif (self.choice.find('gradS') >= 0):
 
             # Ghosts synchronization
-#            OpSynchronize = SynchronizeS(self.topology)
-#            OpSynchronize.apply(self.field2)
+            OpSynchronize = SynchronizeS(self.topology)
+            OpSynchronize.apply(self.field2)
 
             if self.method.find('FD_order2') >= 0:
                 raise ValueError("2nd order scheme Not yet implemented")
@@ -434,8 +467,8 @@ class DifferentialOperator(NumMethod):
         elif self.choice.find('laplacianV') >= 0:
 
             # Ghosts synchronization
-#            OpSynchronize = Synchronize(self.topology)
-#            OpSynchronize.apply(self.field2)
+            OpSynchronize = Synchronize(self.topology)
+            OpSynchronize.apply(self.field2)
 
             if self.method.find('FD_order2') >= 0:
                 raise ValueError("2nd order scheme Not yet implemented")
@@ -583,8 +616,8 @@ class DifferentialOperator(NumMethod):
         elif self.choice.find('curl') >= 0:
 
             # Ghosts synchronization
-#            OpSynchronize = Synchronize(self.topology)
-#            OpSynchronize.apply(self.field1)
+            OpSynchronize = Synchronize(self.topology)
+            OpSynchronize.apply(self.field1)
 
             if self.method.find('FD_order2') >= 0:
                 raise ValueError("2nd order scheme Not yet implemented")
diff --git a/HySoP/hysop/numerics/fct2op.py b/HySoP/hysop/numerics/fct2op.py
index be96777fc..43b783d77 100644
--- a/HySoP/hysop/numerics/fct2op.py
+++ b/HySoP/hysop/numerics/fct2op.py
@@ -71,8 +71,8 @@ class Fct2Op(object):
                                                             y[1][ind0a:ind0b,ind1a:ind1b,ind2a:ind2b] + \
                                                         self.field2[8][ind0a:ind0b,ind1a:ind1b,ind2a:ind2b]* \
                                                             y[2][ind0a:ind0b,ind1a:ind1b,ind2a:ind2b]
-            result = np.concatenate((np.array([temp0]),np.array([temp1]),np.array([temp2])))
-            return result
+#            result = np.concatenate((np.array([temp0]),np.array([temp1]),np.array([temp2])))
+            return temp0, temp1, temp2
 
         if self.choice == 'divWU' : # field2 = velocity field
             result = DifferentialOperator(y, self.field2, self.method, self.choice).__call__()
diff --git a/HySoP/hysop/numerics/integrators/euler.py b/HySoP/hysop/numerics/integrators/euler.py
index 8c02801bd..57bbb3f91 100755
--- a/HySoP/hysop/numerics/integrators/euler.py
+++ b/HySoP/hysop/numerics/integrators/euler.py
@@ -38,8 +38,14 @@ class Euler(ODESolver):
         @param t : current time.
         @param dt : time step.
 #        """
-        result = y + dt * np.asarray(f(t, y), dtype=PARMES_REAL, order=ORDER)
-        return result
+#        result = y + dt * np.asarray(f(t, y), dtype=PARMES_REAL, order=ORDER)
+#        return result
+
+        RHS = f(t, y)
+
+        return y[0] + dt * RHS[0], \
+               y[1] + dt * RHS[1], \
+               y[2] + dt * RHS[2]
 
     def __str__(self):
         """ToString method"""
diff --git a/HySoP/hysop/numerics/integrators/runge_kutta2.py b/HySoP/hysop/numerics/integrators/runge_kutta2.py
index 8a66b71a6..3419c2e33 100755
--- a/HySoP/hysop/numerics/integrators/runge_kutta2.py
+++ b/HySoP/hysop/numerics/integrators/runge_kutta2.py
@@ -37,12 +37,22 @@ class RK2(ODESolver):
         @param y : function Y(t,space)
         """
 
-        # K1 = dt *f[t,y(t,x,y,z)]
-        K1 = dt * np.asarray(f(t, y), dtype=PARMES_REAL, order=ORDER)
-        # result = y(t,x,y,z)] + dt *f[t + dt/2 , y(t,x,y,z) + k1/2.]
-        result = y + dt * np.asarray(f(t + dt / 2., y + K1 / 2.),
-                                     dtype=PARMES_REAL, order=ORDER)
-        return result
+#        # K1 = dt *f[t,y(t,x,y,z)]
+#        K1 = dt * np.asarray(f(t, y), dtype=PARMES_REAL, order=ORDER)
+#        # result = y(t,x,y,z)] + dt *f[t + dt/2 , y(t,x,y,z) + k1/2.]
+
+#        result = y + dt * np.asarray(f(t + dt / 2., y + K1 / 2.),
+#                                     dtype=PARMES_REAL, order=ORDER)
+#        return result
+
+        RHS1 = f(t, y)
+        K1 = np.array([dt * RHS1[0], dt * RHS1[1], dt * RHS1[2]])
+
+        RHS2 = f(t + dt / 2., y + K1 / 2.)
+
+        return y[0] + dt * RHS2[0], \
+               y[1] + dt * RHS2[1], \
+               y[2] + dt * RHS2[2]
 
     def __str__(self):
         """ToString method"""
diff --git a/HySoP/hysop/numerics/integrators/runge_kutta3.py b/HySoP/hysop/numerics/integrators/runge_kutta3.py
index 454fc4604..c5de5014f 100755
--- a/HySoP/hysop/numerics/integrators/runge_kutta3.py
+++ b/HySoP/hysop/numerics/integrators/runge_kutta3.py
@@ -36,16 +36,30 @@ class RK3(ODESolver):
         @param dt : time step.
         @param y : function Y(t,space)
         """
-        # K1 = dt *f[t,y(t,x,y,z)]
-        K1 = dt * np.asarray(f(t, y), dtype=PARMES_REAL, order=ORDER)
-        # result = y(t,x,y,z)] + dt *f[t + dt/2 , y(t,x,y,z) + k1/2.]
-        K2 = dt * np.asarray(f(t + dt / 3., y + K1[:, :, :, :] / 3.),
-                             dtype=PARMES_REAL, order=ORDER)
-        K3 = dt * np.asarray(f(t + dt * 2. / 3., y + K2[:, :, :, :] * 2. / 3.),
-                             dtype=PARMES_REAL, order=ORDER)
+#        # K1 = dt *f[t,y(t,x,y,z)]
+#        K1 = dt * np.asarray(f(t, y), dtype=PARMES_REAL, order=ORDER)
+#        # result = y(t,x,y,z)] + dt *f[t + dt/2 , y(t,x,y,z) + k1/2.]
+#        K2 = dt * np.asarray(f(t + dt / 3., y + K1[:, :, :, :] / 3.),
+#                             dtype=PARMES_REAL, order=ORDER)
+#        K3 = dt * np.asarray(f(t + dt * 2. / 3., y + K2[:, :, :, :] * 2. / 3.),
+#                             dtype=PARMES_REAL, order=ORDER)
+#        # result = y(t,x,y,z)] + 1/4 [ k1 + 3 k3]
+#        result = y + 1. / 4. * (K1 + 3. * K3)
+#        return result
+
+        RHS1 = f(t, y)
+        K1 = np.array([dt * RHS1[0], dt * RHS1[1], dt * RHS1[2]])
+
+        RHS2 = f(t + dt / 3., y + K1 / 3.)
+        K2 =  np.array([dt * RHS2[0], dt * RHS2[1], dt * RHS2[2]])
+
+        RHS3 = f(t + dt * 2. / 3., y + K2 * 2. / 3.)
+        K3 = np.array([dt * RHS3[0], dt * RHS3[1], dt * RHS3[2]])
+
         # result = y(t,x,y,z)] + 1/4 [ k1 + 3 k3]
-        result = y + 1. / 4. * (K1 + 3. * K3)
-        return result
+        return y[0] + 1. / 4. * (K1[0] + 3. * K3[0]), \
+               y[1] + 1. / 4. * (K1[1] + 3. * K3[1]), \
+               y[2] + 1. / 4. * (K1[2] + 3. * K3[2])
 
     def __str__(self):
         """ToString method"""
diff --git a/HySoP/hysop/numerics/integrators/runge_kutta4.py b/HySoP/hysop/numerics/integrators/runge_kutta4.py
index 286d9fc1b..679352b67 100755
--- a/HySoP/hysop/numerics/integrators/runge_kutta4.py
+++ b/HySoP/hysop/numerics/integrators/runge_kutta4.py
@@ -38,18 +38,35 @@ class RK4(ODESolver):
         @param y : function Y(t,space)
         """
 
-        # K1 = dt *f[t, y(t, x, y, z)]
-        K1 = dt * np.asarray(f(t, y), dtype=PARMES_REAL, order=ORDER)
-        K2 = dt * np.asarray(f(t + dt / 2., y + K1[:, :, :, :] / 2.),
-                             dtype=PARMES_REAL, order=ORDER)
-        K3 = dt * np.asarray(f(t + dt / 2., y + K2[:, :, :, :] / 2.),
-                             dtype=PARMES_REAL, order=ORDER)
-        K4 = dt * np.asarray(f(t + dt, y + K3[:, :, :, :]),
-                             dtype=PARMES_REAL, order=ORDER)
+#        # K1 = dt *f[t, y(t, x, y, z)]
+#        K1 = dt * np.asarray(f(t, y), dtype=PARMES_REAL, order=ORDER)
+#        K2 = dt * np.asarray(f(t + dt / 2., y + K1[:, :, :, :] / 2.),
+#                             dtype=PARMES_REAL, order=ORDER)
+#        K3 = dt * np.asarray(f(t + dt / 2., y + K2[:, :, :, :] / 2.),
+#                             dtype=PARMES_REAL, order=ORDER)
+#        K4 = dt * np.asarray(f(t + dt, y + K3[:, :, :, :]),
+#                             dtype=PARMES_REAL, order=ORDER)
+#        # result = y(t, x, y, z)]  +  dt *f[t + dt/2 ,  y(t, x, y, z) + k1/2.]
+#        result = y + 1. / 6. * (K1[:, :, :, :] + 2. * K2[:, :, :, :] +
+#                                2. * K3[:, :, :, :] + K4[:, :, :, :])
+#        return result
+
+        RHS1 = f(t, y)
+        K1 = np.array([dt * RHS1[0], dt * RHS1[1], dt * RHS1[2]])
+
+        RHS2 = f(t + dt / 2., y + K1 / 1.)
+        K2 =  np.array([dt * RHS2[0], dt * RHS2[1], dt * RHS2[2]])
+
+        RHS3 = f(t + dt * 2., y + K2 * 2.)
+        K3 = np.array([dt * RHS3[0], dt * RHS3[1], dt * RHS3[2]])
+
+        RHS4 = f(t + dt, y + K3)
+        K4 = np.array([dt * RHS4[0], dt * RHS4[1], dt * RHS4[2]])
+
         # result = y(t, x, y, z)]  +  dt *f[t + dt/2 ,  y(t, x, y, z) + k1/2.]
-        result = y + 1. / 6. * (K1[:, :, :, :] + 2. * K2[:, :, :, :] +
-                                2. * K3[:, :, :, :] + K4[:, :, :, :])
-        return result
+        return y[0] + 1. / 6. * (K1[0] + 2. * K2[0] + 2. * K3[0] + K4[0]), \
+               y[1] + 1. / 6. * (K1[1] + 2. * K2[1] + 2. * K3[1] + K4[1]), \
+               y[2] + 1. / 6. * (K1[2] + 2. * K2[2] + 2. * K3[2] + K4[2])
 
     def __str__(self):
         """ToString method"""
diff --git a/HySoP/hysop/operator/discrete/stretching.py b/HySoP/hysop/operator/discrete/stretching.py
index 227d9bb7a..3d55cbc29 100755
--- a/HySoP/hysop/operator/discrete/stretching.py
+++ b/HySoP/hysop/operator/discrete/stretching.py
@@ -60,9 +60,7 @@ class Stretching_d(DiscreteOperator):
         else:
             self.num_method = RK3
             self.cststretch = 2.5127
-        self.cststretch = self.cststretch / 2.
 
-    @debug
     @timed_function
     def apply(self, simulation):
         """
@@ -106,13 +104,13 @@ class Stretching_d(DiscreteOperator):
                     method='FD_order4',
                     choice='gradV')
 
-                gradResult, maxgersh = self.stretchOp()
+                gradResult, maxArray, divergence = self.stretchOp()
 
-                print "Maxgersh", maxgersh
-                print "dtAdvec", 0.5 / maxgersh[1]
+                print "maxadv, maxgersh", maxArray[1], maxArray[0]
+                print "dtAdvec", 0.5 / maxArray[1]
 
                 ## Determination of Stretching time step (stability condition)
-                self.ndt = self.stabilityTest(dt, maxgersh[0],
+                self.ndt = self.stabilityTest(dt, maxArray[0],
                                               self.num_method, self.cststretch)
                 self.dtstretch = dt / float(self.ndt)
 
@@ -127,9 +125,14 @@ class Stretching_d(DiscreteOperator):
             t = simulation.time
             for i in range(self.ndt):
                 methodInt = self.num_method(self.function)
-                self.vorticity.data[...] = methodInt(self.function.apply,
-                                                     t, self.dtstretch,
-                                                     self.vorticity.data)
+#                self.vorticity.data[...] = methodInt(self.function.apply,
+#                                                     t, self.dtstretch,
+#                                                     self.vorticity.data)
+                self.vorticity.data[0][...], \
+                self.vorticity.data[1][...], \
+                self.vorticity.data[2][...] = methodInt(self.function.apply,
+                                                        t, self.dtstretch,
+                                                        self.vorticity.data)
 #            print 'norm omega', LA.norm(self.vorticity.data)
 
     def stabilityTest(self, dt, maxi, num_method, cststretch):
diff --git a/HySoP/hysop/operator/monitors/printer.py b/HySoP/hysop/operator/monitors/printer.py
index 2e0f1c32d..0b7ae2597 100644
--- a/HySoP/hysop/operator/monitors/printer.py
+++ b/HySoP/hysop/operator/monitors/printer.py
@@ -117,7 +117,8 @@ class Printer(Monitoring):
             print "Print to file " + filename
             ## VTK output \todo: Need fix in 2D, getting an IOError.
             try:
-                evtk.imageToVTK(filename, pointData=self._build_vtk_dict())
+                orig = self.variables[0].discreteFields.values()[0].topology.mesh.global_start
+                evtk.imageToVTK(filename, origin=(orig[0], orig[1], orig[2]), pointData=self._build_vtk_dict())
             except IOError:
                 if self.variables[0].domain.dimension == 2:
                     ## Standard output
-- 
GitLab