From 2e0054f3b7701df00240ae35708d504809beece1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franck=20P=C3=A9rignon?= <franck.perignon@imag.fr>
Date: Thu, 23 May 2013 15:10:35 +0000
Subject: [PATCH] Add field serialization methods

---
 HySoP/hysop/fields/continuous.py | 31 +++++++++++++++++++++++++
 HySoP/hysop/fields/discrete.py   | 40 ++++++++++++++++++++++++++++++--
 HySoP/hysop/fields/scalar.py     | 19 +++++++++++----
 3 files changed, 83 insertions(+), 7 deletions(-)

diff --git a/HySoP/hysop/fields/continuous.py b/HySoP/hysop/fields/continuous.py
index 521f79235..0fd1e9c64 100644
--- a/HySoP/hysop/fields/continuous.py
+++ b/HySoP/hysop/fields/continuous.py
@@ -169,6 +169,37 @@ class Field(object):
         """
         self.extraParameters = args
 
+    def dump(self, filename, topo=None):
+        """
+        Dump (serialize) the data of the field into filename.
+        serialization process.
+        @param filename : name of the file in which data are serialized
+        @param topo : topology that identify a discrete field to be saved.
+        if None, the first discrete field in the list will be saved.
+        """
+        if topo is not None:
+            assert topo in self.discreteFields.keys()
+            self.discreteFields[topo].dump(filename)
+        else:
+            # dump all discr or only the first one?
+            self.discreteFields.values()[0].dump(filename)
+
+    def load(self, filename, topo=None):
+        """
+        load data from a file build
+        with cPickle serialization.
+        @param filename : name of the file in which data are serialized
+        @param topo : topology that identify a discrete field to be saved.
+        if None, the first discrete field in the list will be saved.
+        """
+        if topo is not None:
+            assert topo in self.discreteFields.keys()
+            self.discreteFields[topo].load(filename)
+        else:
+            # dump all discr or only the first one?
+            self.discreteFields.values()[0].load(filename)
+
+
 if __name__ == "__main__":
     print __doc__
     print "- Provided class : ContinuousField"
diff --git a/HySoP/hysop/fields/discrete.py b/HySoP/hysop/fields/discrete.py
index 1ff8f84cb..12ff4c1a5 100644
--- a/HySoP/hysop/fields/discrete.py
+++ b/HySoP/hysop/fields/discrete.py
@@ -5,6 +5,9 @@ Abstract interface to discrete fields (scalars or vectors) descriptions.
 """
 from abc import ABCMeta, abstractmethod
 from parmepy.constants import debug
+from scitools.NumPyDB import NumPyDB_cPickle
+from itertools import count
+from parmepy.mpi import main_rank
 
 
 class DiscreteField(object):
@@ -56,6 +59,10 @@ class DiscreteField(object):
 
     __metaclass__ = ABCMeta
 
+    ## Counter for discrete field instanciations.
+    ## Used to set default name and for serialization ids.
+    __field_counter = count(0)
+
     @debug
     def __new__(cls, *args, **kw):
         return object.__new__(cls, *args, **kw)
@@ -72,12 +79,13 @@ class DiscreteField(object):
         ## Topology informations.
         self.topology = topology
 
+        ## Id (unique) for the field
+        self.__id = self.__field_counter.next()
         ## Field name.
         if name is not None:
             self.name = name
         else:
-            self.name = 'Unamed'
-
+            self.name = 'd_field_' + str(self.__id)
         ## Field dimension.
         self.dimension = topology.domain.dimension
         ## Field resolution.
@@ -92,6 +100,7 @@ class DiscreteField(object):
         self.isVector = None
         ## Field data numpy array.
         self.data = None
+        ## An id (optional) used to identify the field for
 
     @abstractmethod
     def __getitem__(self, i):
@@ -109,6 +118,33 @@ class DiscreteField(object):
     def get_data_method(self):
         pass
 
+    def dump(self, filename):
+        """
+        Dump (serialize) the data of the field into filename.
+        @param filename : name of the file in which data are serialized
+        """
+        filename += '_rk_'
+        filename += str(main_rank)
+        db = NumPyDB_cPickle(filename, mode='store')
+        #for dim in xrange(self.dimension):
+        #    idd = self.name + '_' + str(dim)
+        db.dump(self.data, self.name)
+
+    def load(self, filename):
+        """
+        load data from a file build
+        with cPickle serialization.
+        @param filename : name of the file in which data are serialized
+        """
+        filename += '_rk_'
+        filename += str(main_rank)
+        db = NumPyDB_cPickle(filename, mode='load')
+        if self.isVector:
+            for dim in xrange(self.dimension):
+                self.data[dim] = db.load(self.name)[0][dim]
+        else:
+            self.data = db.load(self.name)[0]
+
 if __name__ == "__main__":
     print __doc__
     print "- Provided class : Domain (abstract)."
diff --git a/HySoP/hysop/fields/scalar.py b/HySoP/hysop/fields/scalar.py
index 2999a1e76..be92d02e3 100644
--- a/HySoP/hysop/fields/scalar.py
+++ b/HySoP/hysop/fields/scalar.py
@@ -61,13 +61,22 @@ class ScalarField(DiscreteField):
         if formula is not None:
             v_formula = np.vectorize(formula)
             if self.dimension == 3:
-                self.data[...] = v_formula(*(self.topology.mesh.coords + args))
+                self.data[...] = np.asarray(
+                    v_formula(*(self.topology.mesh.coords + args)),
+                    dtype=PARMES_REAL,
+                    order=ORDER)
+
             elif self.dimension == 2:
-                self.data[...] = v_formula(*(self.topology.mesh.coords + args))
+                self.data[...] = np.asarray(
+                    v_formula(*(self.topology.mesh.coords + args)),
+                    dtype=PARMES_REAL,
+                    order=ORDER)
+
             else:
-                self.data[...] = formula(*(self.topology.mesh.coords + args))
-            self.data[...] = np.asarray(self.data,
-                                        dtype=PARMES_REAL, order=ORDER)
+                self.data[...] = np.asarray(
+                    formula(*(self.topology.mesh.coords + args)),
+                    dtype=PARMES_REAL,
+                    order=ORDER)
         else:
             self.data[...] = 0.0
 
-- 
GitLab