From 13f5c27ddc84f1f06d186c25f3a206afeeb4255b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Franck=20P=C3=A9rignon?= <franck.perignon@imag.fr>
Date: Tue, 16 Apr 2013 08:59:48 +0000
Subject: [PATCH] Add missing class for data redistribution

---
 HySoP/hysop/operator/redistribute.py | 118 +++++++++++++++++++++++++++
 1 file changed, 118 insertions(+)
 create mode 100644 HySoP/hysop/operator/redistribute.py

diff --git a/HySoP/hysop/operator/redistribute.py b/HySoP/hysop/operator/redistribute.py
new file mode 100644
index 000000000..442cccf2e
--- /dev/null
+++ b/HySoP/hysop/operator/redistribute.py
@@ -0,0 +1,118 @@
+"""
+@file redistribute.py
+Setup for data transfer/redistribution between two parmes topologies.
+
+This operator is an inter operator which is supposed to define the process to
+transfer variables and data from one operator to another.
+This mainly concerns data redistribution if the two operators work on
+different mpi topologies.
+
+When is it required to define an operator between op1 and op2?
+If:
+- the intersection between op1.output-variables and op2.input-variables
+  is not empty
+- AND if the topology on which the variables of op1 are defined is different
+from the one of op2 variables.
+
+Note Franck: this kind of operator may also be useful
+to define the interpolation/filter process for data transfer for
+a variable defined on several meshes.
+
+"""
+
+from parmepy.constants import debug
+from parmepy.operator.continuous import Operator
+from parmepy.mpi.topology import Bridge
+
+
+class Redistribute(Operator):
+    """
+    Interconnection between two operators.
+    SetUp will compute (or get if it already exists) a Bridge between two
+    topologies.
+    Apply redistributes data from opFrom topology to opTo topology.
+
+    """
+    @debug
+    def __init__(self, variables, opFrom, opTo):
+
+        """
+        Create an operator to distribute data between two mpi topologies for a
+        list of variables belonging to two operators.
+
+        @param variables : the set of variables to be redistributed
+        @param opFrom : source operator
+        @param opTo : target (i.e.) the operator that handles the topology on
+        which data must be redistributed.
+        """
+
+        if isinstance(variables, list):
+            Operator.__init__(self, variables)
+        else:
+            Operator.__init__(self, [variables])
+
+        ## Source Operator
+        self.opFrom = opFrom
+        ## Targeted operator
+        self.opTo = opTo
+
+        # Then check if variables belong to both operators
+        for v in self.variables:
+            assert v in opFrom.variables and v in opTo.variables, \
+                'Redistribute error : one of the variable is not present\
+                in both source and target operator.'
+
+    @debug
+    def setUp(self):
+        """
+        Computes intersection of two topologies.
+
+        """
+        assert self.opFrom.isUp and self.opTo.isUp(), \
+            'You should setup both opFrom and opTo operators\
+            before any attempt to setup a redistribute operator.'
+
+        self.bridges = {}
+        for v in self.variables:
+            vd_from = self.opFrom.discreteFields[v]
+            vd_to = self.opTo.discreteFields[v]
+            self.bridges[v] = Bridge(vd_from.topology, vd_to.topology)
+
+        self._isUpToDate = True
+
+    def apply(self):
+        """
+        Proceed with data redistribution from opFrom to opTo
+        """
+        dim = self.domain.dimension
+        for v in self.variables:
+            br = self.bridges[v]
+            if v.isVector:
+                # Apply for each component of the data
+                for d in range(dim):
+                    vTo = self.opTo.discreteFields[v].data[d]
+                    vFrom = self.opFrom.discreteFields[v].data[d]
+                    vTo[br.ito] = vFrom[br.ifrom]
+
+            # scalar
+            else:
+                vTo = self.opTo.discreteFields[v].data
+                vFrom = self.opFrom.discreteFields[v].data
+                vTo[br.ito] = vFrom[br.ifrom]
+        #from parmepy.mpi import main_rank
+
+
+#        for rk in br.recvFrom.keys():
+ #           main_rank.Irecv()
+
+    def __str__(self):
+        """ToString method"""
+        s = "Bridge from :\n " + str(self.opFrom)
+        s += "\n to operator:\n " + str(self.opTo)
+        s += "for variable(s) " + str([v.name for v in self.variables])
+        return s + "\n"
+
+if __name__ == "__main__":
+    print __doc__
+    print "- Provided class : Redistribute"
+    print Redistribute.__doc__
-- 
GitLab