Raw File
ContainingCoupler.py
#!/usr/bin/env python
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
#<LicenseText>
#
# CitcomS.py by Eh Tan, Eun-seo Choi, and Pururav Thoutireddy.
# Copyright (C) 2002-2005, California Institute of Technology.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#</LicenseText>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#

from Coupler import Coupler

class ContainingCoupler(Coupler):


    def __init__(self, name, facility):
        Coupler.__init__(self, name, facility)
        return


    def initialize(self, solver):
        Coupler.initialize(self, solver)
        return


    def createMesh(self):
        # Create BoundedMesh objects.
     
        from ExchangerLib import createGlobalBoundedBox, exchangeBoundedBox, createInterior, createEmptyBoundary

        # the bounding box of the mesh on this solver
        self.globalBBox = createGlobalBoundedBox(self.all_variables)

        # the bounding box of the mesh on the other solver
        self.remoteBBox = exchangeBoundedBox(self.globalBBox,
                                             self.communicator.handle(),
                                             self.srcCommList[0].handle(),
                                             self.srcCommList[0].size - 1)

        # the nodes within remoteBBox
        self.interior, self.myBBox = createInterior(self.remoteBBox,
                                                    self.all_variables)

        self.remoteBdryList = range(self.remoteSize)
        for i in range(self.remoteSize):
            # an empty boundary object for remote velocity nodes
            # will be filled by a remote boundary obj.
            self.remoteBdryList[i] = createEmptyBoundary()

        return


    def createSourceSink(self):
        # create source first, then sink. The order is important.
        self.createSource()

        if self.inventory.two_way_communication:
            self.createSink()
        return


    def createSource(self):
        # the source obj's will send boundary conditions to a remote sink
        from ExchangerLib import CitcomSource_create
        self.sourceList = range(self.remoteSize)
        for i, comm, b in zip(range(self.remoteSize),
                              self.srcCommList,
                              self.remoteBdryList):
            # sink is always in the last rank of a communicator
            sinkRank = comm.size - 1

            # the sources will communicate with the sink in EmbeddedCoupler
            # during creation stage
            self.sourceList[i] = CitcomSource_create(comm.handle(),
                                                     sinkRank,
                                                     b,
                                                     self.myBBox,
                                                     self.all_variables)

        if self.inventory.exchange_pressure:
            from ExchangerLib import createEmptyPInterior
            self.pinterior = range(self.remoteSize)

            for i in range(self.remoteSize):
                self.pinterior[i] = createEmptyPInterior()

            self.psourceList = range(self.remoteSize)
            for i, comm, b in zip(range(self.remoteSize),
                                  self.srcCommList,
                                  self.pinterior):
                # sink is always in the last rank of a communicator
                sinkRank = comm.size - 1
                self.psourceList[i] = CitcomSource_create(comm.handle(),
                                                          sinkRank,
                                                          b,
                                                          self.myBBox,
                                                          self.all_variables)
        return


    def createSink(self):
        # the sink obj. will receive interior temperature from remote sources
        from ExchangerLib import Sink_create

        # the sink will communicate with the source in EmbeddedCoupler
        # during creation stage
        self.sink = Sink_create(self.sinkComm.handle(),
                                self.remoteSize,
                                self.interior)
        return


    def createBC(self):
        # boundary conditions will be sent by SVTOutlet, which sends
        # stress, velocity, and temperature
        import Outlet
        self.outletList = range(self.remoteSize)
        for i, src in zip(range(self.remoteSize),
                          self.sourceList):
            self.outletList[i] = Outlet.SVTOutlet(src, self.all_variables)

        if self.inventory.exchange_pressure:
            self.poutletList = range(self.remoteSize)
            for i, src in zip(range(self.remoteSize),
                              self.psourceList):

                self.poutletList[i] = Outlet.POutlet(src, self.all_variables)

        return


    def createII(self):
        # interior temperature will be received by TInlet
        import Inlet
        self.inlet = Inlet.TInlet(self.interior,
                                  self.sink,
                                  self.all_variables)
        return


    def initTemperature(self):
        from ExchangerLib import initTemperature
        initTemperature(self.remoteBBox,
                        self.all_variables)
        return


    def exchangeTemperature(self):
        if not self.inventory.exchange_initial_temperature:
            return

        from ExchangerLib import createEmptyInterior, CitcomSource_create
        interior = range(self.remoteSize)
        source = range(self.remoteSize)

        for i in range(len(interior)):
            interior[i] = createEmptyInterior()

        for i, comm, b in zip(range(self.remoteSize),
                              self.srcCommList,
                              interior):
            # sink is always in the last rank of a communicator
            sinkRank = comm.size - 1
            source[i] = CitcomSource_create(comm.handle(),
                                            sinkRank,
                                            b,
                                            self.myBBox,
                                            self.all_variables)

        import Outlet
        for i, src in zip(range(self.remoteSize), source):
            outlet = Outlet.TOutlet(src, self.all_variables)
            outlet.send()

        # Any modification of read-in temperature is done here
        # Note: modifyT is called after sending unmodified T to EmbeddedCoupler.
        # If T is modified before sending, EmbeddedCoupler's T will lose sharp
        # feature.
        # EmbeddedCoupler has to call modifyT too to ensure consistent T field.
        #self.modifyT(self.remoteBBox)

        return


    def postVSolverRun(self):
        # send computed velocity to ECPLR for its BCs
        for outlet in self.outletList:
            outlet.send()

        if self.inventory.exchange_pressure:
            for outlet in self.poutletList:
                outlet.send()
        return


    def newStep(self):
        # update the temperature field in the overlapping region
        if self.inventory.two_way_communication:
            # receive temperture field from EmbeddedCoupler
            self.inlet.recv()
            self.inlet.impose()
        return


    def stableTimestep(self, dt):
        from ExchangerLib import exchangeTimestep
        remote_dt = exchangeTimestep(dt,
                                     self.communicator.handle(),
                                     self.srcCommList[0].handle(),
                                     self.srcCommList[0].size - 1)

        assert remote_dt < dt, \
               'Size of dt in the esolver is greater than dt in the csolver!'

        #print "%s - old dt = %g   exchanged dt = %g" % (
        #       self.__class__, dt, remote_dt)
        return dt


    def exchangeSignal(self, signal):
        from ExchangerLib import exchangeSignal
        newsgnl = exchangeSignal(signal,
                                 self.communicator.handle(),
                                 self.srcCommList[0].handle(),
                                 self.srcCommList[0].size - 1)
        return newsgnl



    class Inventory(Coupler.Inventory):

        import pyre.inventory as prop






# version
__id__ = "$Id$"

# End of file
back to top