[cig-commits] r7530 - in mc/3D/CitcomS/trunk/CitcomS: . Coupler
Solver
tan2 at geodynamics.org
tan2 at geodynamics.org
Tue Jun 26 18:04:41 PDT 2007
Author: tan2
Date: 2007-06-26 18:04:41 -0700 (Tue, 26 Jun 2007)
New Revision: 7530
Modified:
mc/3D/CitcomS/trunk/CitcomS/BaseApplication.py
mc/3D/CitcomS/trunk/CitcomS/Controller.py
mc/3D/CitcomS/trunk/CitcomS/CoupledApp.py
mc/3D/CitcomS/trunk/CitcomS/Coupler/ContainingCoupler.py
mc/3D/CitcomS/trunk/CitcomS/Coupler/Coupler.py
mc/3D/CitcomS/trunk/CitcomS/Coupler/EmbeddedCoupler.py
mc/3D/CitcomS/trunk/CitcomS/Layout.py
mc/3D/CitcomS/trunk/CitcomS/SimpleApp.py
mc/3D/CitcomS/trunk/CitcomS/Solver/CoupledSolver.py
Log:
Added/updated a bunch of comments, renamed variables
Modified: mc/3D/CitcomS/trunk/CitcomS/BaseApplication.py
===================================================================
--- mc/3D/CitcomS/trunk/CitcomS/BaseApplication.py 2007-06-26 20:32:09 UTC (rev 7529)
+++ mc/3D/CitcomS/trunk/CitcomS/BaseApplication.py 2007-06-27 01:04:41 UTC (rev 7530)
@@ -35,6 +35,8 @@
def __init__(self, name="CitcomS"):
+ '''Constructor. Inventory object is not initialized yet.
+ '''
Application.__init__(self, name)
self._info = journal.debug("application")
@@ -43,13 +45,19 @@
def _init(self):
+ '''Called by mpi.Application.__init__(). Inventory object becomes available.
+ '''
Application._init(self)
+
+ # self.nodes is the # of CPUs for this simulation
self.nodes = self.getNodes()
return
def main(self, *args, **kwds):
+ '''The entry point, like main() in C.
+ '''
self.initialize()
self.reportConfiguration()
self.launch()
@@ -58,6 +66,8 @@
def launch(self):
+ '''Start the computation.
+ '''
self.controller.launch(self)
self.controller.march(steps=self.inventory.steps)
@@ -66,6 +76,8 @@
def _getPrivateDepositoryLocations(self):
+ '''Find the location of *.odb files.
+ '''
from os.path import dirname, isdir, join
list = []
etc = join(dirname(dirname(__file__)), 'etc')
Modified: mc/3D/CitcomS/trunk/CitcomS/Controller.py
===================================================================
--- mc/3D/CitcomS/trunk/CitcomS/Controller.py 2007-06-26 20:32:09 UTC (rev 7529)
+++ mc/3D/CitcomS/trunk/CitcomS/Controller.py 2007-06-27 01:04:41 UTC (rev 7530)
@@ -60,6 +60,8 @@
def launch(self, app):
+ '''Setup initial conditions.
+ '''
# 0th step
self.solver.launch(app)
@@ -78,13 +80,13 @@
while 1:
- # notify solvers we are starting a new timestep
+ # notify solver we are starting a new timestep
self.startTimestep()
# compute an acceptable timestep
dt = self.stableTimestep()
- # advance
+ # advance to the next step by dt
self.advance(dt)
# notify solver we finished a timestep
Modified: mc/3D/CitcomS/trunk/CitcomS/CoupledApp.py
===================================================================
--- mc/3D/CitcomS/trunk/CitcomS/CoupledApp.py 2007-06-26 20:32:09 UTC (rev 7529)
+++ mc/3D/CitcomS/trunk/CitcomS/CoupledApp.py 2007-06-27 01:04:41 UTC (rev 7530)
@@ -49,10 +49,15 @@
def getNodes(self):
+ # csolver requires nproc1 CPUs to run
s1 = self.inventory.csolver.inventory.mesher.inventory
nproc1 = s1.nproc_surf * s1.nprocx * s1.nprocy * s1.nprocz
+
+ # esolver requires nproc2 CPUs to run
s2 = self.inventory.esolver.inventory.mesher.inventory
nproc2 = s2.nproc_surf * s2.nprocx * s2.nprocy * s2.nprocz
+
+ # the whole application requires nproc1+nproc2 CPUs
return nproc1 + nproc2
@@ -70,7 +75,8 @@
def findLayout(self, layout):
-
+ '''Assigning controller/solver/coupler/communicator to this processor.
+ '''
if layout.ccomm:
# This process belongs to the containing solver
self.controller = self.inventory.ccontroller
Modified: mc/3D/CitcomS/trunk/CitcomS/Coupler/ContainingCoupler.py
===================================================================
--- mc/3D/CitcomS/trunk/CitcomS/Coupler/ContainingCoupler.py 2007-06-26 20:32:09 UTC (rev 7529)
+++ mc/3D/CitcomS/trunk/CitcomS/Coupler/ContainingCoupler.py 2007-06-27 01:04:41 UTC (rev 7530)
@@ -43,38 +43,49 @@
def initialize(self, solver):
- print self.name, 'entering initialize'
Coupler.initialize(self, solver)
# restart and use temperautre field of previous run?
-
self.restart = solver.restart
if self.restart:
self.ic_initTemperature = solver.ic_initTemperature
self.all_variables = solver.all_variables
+
+ # allocate space for exchanger objects
self.boundary = range(self.numSrc)
self.source["BC"] = range(self.numSrc)
self.BC = range(self.numSrc)
+ # init'd Convertor singleton, this must be done before any other
+ # exchanger call
from ExchangerLib import initConvertor
initConvertor(self.inventory.dimensional,
self.inventory.transformational,
self.all_variables)
- print self.name, 'leaving initialize'
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.srcComm[0].handle(),
self.srcComm[0].size - 1)
+
+ # the nodes within remoteBBox
self.interior, self.myBBox = createInterior(self.remoteBBox,
self.all_variables)
+
+ # an empty boundary object, which will be filled by a remote boundary obj.
for i in range(len(self.boundary)):
self.boundary[i] = createEmptyBoundary()
@@ -82,6 +93,7 @@
def createSourceSink(self):
+ # create source first, then sink. The order is important.
self.createSource()
if self.inventory.two_way_communication:
@@ -90,6 +102,7 @@
def createSource(self):
+ # the source obj's will send boundary conditions to a remote sink
from ExchangerLib import CitcomSource_create
for i, comm, b in zip(range(self.numSrc),
self.srcComm,
@@ -106,6 +119,7 @@
def createSink(self):
+ # the sink obj. will receive interior temperature from remote sources
from ExchangerLib import Sink_create
self.sink["Intr"] = Sink_create(self.sinkComm.handle(),
self.numSrc,
@@ -114,6 +128,8 @@
def createBC(self):
+ # boundary conditions will be sent by SVTOutlet, which sends
+ # stress, velocity, and temperature
import Outlet
for i, src in zip(range(self.numSrc),
self.source["BC"]):
@@ -123,6 +139,7 @@
def createII(self):
+ # interior temperature will be received by TInlet
import Inlet
self.II = Inlet.TInlet(self.interior,
self.sink["Intr"],
@@ -135,7 +152,7 @@
# read-in restarted temperature field
self.ic_initTemperature()
del self.ic_initTemperature
- # send temperature to FGE and postprocess
+ # send temperature to EmbeddedCoupler and postprocess
self.restartTemperature()
else:
from ExchangerLib import initTemperature
@@ -169,22 +186,25 @@
outlet.send()
# Any modification of read-in temperature is done here
- # Note: modifyT is called after sending unmodified T to FGE.
- # If T is modified before sending, FGE's T will lose sharp feature.
- # FGE has to call modifyT too to ensure consistent T field.
+ # 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
self.applyBoundaryConditions()
return
def newStep(self):
+ # update the temperature field in the overlapping region
if self.inventory.two_way_communication:
- # receive temperture field from FGE
+ # receive temperture field from EmbeddedCoupler
self.II.recv()
self.II.impose()
return
Modified: mc/3D/CitcomS/trunk/CitcomS/Coupler/Coupler.py
===================================================================
--- mc/3D/CitcomS/trunk/CitcomS/Coupler/Coupler.py 2007-06-26 20:32:09 UTC (rev 7529)
+++ mc/3D/CitcomS/trunk/CitcomS/Coupler/Coupler.py 2007-06-27 01:04:41 UTC (rev 7530)
@@ -45,7 +45,7 @@
self.sink = {}
self.source = {}
- self.catchup = True
+ self.synchronized = True
self.done = False
self.coupled_steps = 1
return
@@ -62,6 +62,7 @@
def launch(self, solver):
+ # these functions are defined in the subclass
self.createMesh()
self.createSourceSink()
self.createBC()
@@ -72,6 +73,7 @@
def modifyT(self, bbox):
+ # modify read-in temperature field
from ExchangerLib import modifyT
modifyT(bbox, self.all_variables)
return
@@ -88,34 +90,36 @@
def endTimestep(self, steps, done):
+ # exchange predefined signal btwn couplers
+ # the signal is used to sync the timesteps
KEEP_WAITING_SIGNAL = 0
NEW_STEP_SIGNAL = 1
END_SIMULATION_SIGNAL = 2
if done:
sent = END_SIMULATION_SIGNAL
- elif self.catchup:
+ elif self.synchronized:
sent = NEW_STEP_SIGNAL
else:
sent = KEEP_WAITING_SIGNAL
while 1:
- signal = self.exchangeSignal(sent)
+ recv = self.exchangeSignal(sent)
- if done or (signal == END_SIMULATION_SIGNAL):
+ if done or (recv == END_SIMULATION_SIGNAL):
done = True
break
- elif signal == KEEP_WAITING_SIGNAL:
+ elif recv == KEEP_WAITING_SIGNAL:
pass
- elif signal == NEW_STEP_SIGNAL:
- if self.catchup:
+ elif recv == NEW_STEP_SIGNAL:
+ if self.synchronized:
#print self.name, 'exchanging timestep =', steps
self.coupled_steps = self.exchangeSignal(steps)
#print self.name, 'exchanged timestep =', self.coupled_steps
break
else:
raise ValueError, \
- "Unexpected signal value, singnal = %d" % signal
+ "Unexpected signal value, singnal = %d" % recv
return done
@@ -130,7 +134,9 @@
# if dimensional is True, quantities exchanged are dimensional
dimensional = prop.bool("dimensional", default=True)
- # if transformational is True, quantities exchanged are in standard coordiate system
+
+ # if transformational is True, quantities exchanged are in standard
+ # (ie. Cartesian) coordinate system
transformational = prop.bool("transformational", default=True)
Modified: mc/3D/CitcomS/trunk/CitcomS/Coupler/EmbeddedCoupler.py
===================================================================
--- mc/3D/CitcomS/trunk/CitcomS/Coupler/EmbeddedCoupler.py 2007-06-26 20:32:09 UTC (rev 7529)
+++ mc/3D/CitcomS/trunk/CitcomS/Coupler/EmbeddedCoupler.py 2007-06-27 01:04:41 UTC (rev 7530)
@@ -33,19 +33,25 @@
def __init__(self, name, facility):
Coupler.__init__(self, name, facility)
- self.cge_t = 0
- self.fge_t = 0
+
+ # time of containing coupler
+ self.ccplr_t = 0
+
+ # time of embedded coupler
+ self.ecplr_t = 0
+
+ # whether to apply boundary conditions
self.toApplyBC = True
# exchanged information is non-dimensional
self.inventory.dimensional = False
+
# exchanged information is in spherical coordinate
self.inventory.transformational = False
return
def initialize(self, solver):
- print self.name, 'entering initialize'
Coupler.initialize(self, solver)
# restart and use temperautre field of previous run?
@@ -54,6 +60,8 @@
self.ic_initTemperature = solver.ic_initTemperature
self.all_variables = solver.all_variables
+
+ # allocate space for exchanger objects
self.interior = range(self.numSrc)
self.source["Intr"] = range(self.numSrc)
self.II = range(self.numSrc)
@@ -63,28 +71,38 @@
if not solver.inventory.bc.inventory.side_sbcs:
raise SystemExit('\n\nError: esolver.bc.side_sbcs must be on!\n\n\n')
+ # init'd Convertor singleton, this must be done before any other
+ # exchanger call
from ExchangerLib import initConvertor
initConvertor(self.inventory.dimensional,
self.inventory.transformational,
self.all_variables)
- print self.name, 'leaving initialize'
return
def createMesh(self):
+ '''Create BoundedMesh objects.
+ '''
from ExchangerLib import createGlobalBoundedBox, exchangeBoundedBox, createBoundary, createEmptyInterior
inv = self.inventory
+
+ # 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
mycomm = self.communicator
self.remoteBBox = exchangeBoundedBox(self.globalBBox,
mycomm.handle(),
self.sinkComm.handle(),
0)
+
+ # the nodes on the boundary, top and bottom boundaries are special
self.boundary, self.myBBox = createBoundary(self.all_variables,
inv.excludeTop,
inv.excludeBottom)
+ # an empty interior object, which will be filled by a remote interior obj.
if inv.two_way_communication:
for i in range(len(self.interior)):
self.interior[i] = createEmptyInterior()
@@ -93,6 +111,7 @@
def createSourceSink(self):
+ # create sink first, then source. The order is important.
self.createSink()
if self.inventory.two_way_communication:
@@ -101,6 +120,7 @@
def createSink(self):
+ # the sink obj. will receive boundary conditions from remote sources
from ExchangerLib import Sink_create
self.sink["BC"] = Sink_create(self.sinkComm.handle(),
self.numSrc,
@@ -109,6 +129,7 @@
def createSource(self):
+ # the source obj's will send interior temperature to a remote sink
from ExchangerLib import CitcomSource_create
for i, comm, b in zip(range(self.numSrc),
self.srcComm,
@@ -125,28 +146,17 @@
def createBC(self):
+ # boundary conditions will be recv. by SVTInlet, which receives
+ # stress, velocity, and temperature
import Inlet
self.BC = Inlet.SVTInlet(self.boundary,
self.sink["BC"],
self.all_variables)
- '''
- if self.inventory.incompressibility:
- self.BC = Inlet.BoundaryVTInlet(self.communicator,
- self.boundary,
- self.sink["BC"],
- self.all_variables,
- "VT")
- import journal
- journal.info("incompressibility").activate()
- else:
- self.BC = Inlet.SVTInlet(self.boundary,
- self.sink["BC"],
- self.all_variables)
- '''
return
def createII(self):
+ # interior temperature will be sent by TOutlet
import Outlet
for i, src in zip(range(self.numSrc),
self.source["Intr"]):
@@ -157,7 +167,7 @@
def initTemperature(self):
if self.restart:
- # receive temperature from CGE and postprocess
+ # receive temperature from CCPLR and postprocess
self.restartTemperature()
else:
from ExchangerLib import initTemperature
@@ -179,23 +189,24 @@
inlet.impose()
# Any modification of read-in temperature is done here
- # Note: modifyT is called after receiving unmodified T from CGE.
- # If T is modified before sending, FGE's T will lose sharp feature.
- # CGE has to call modifyT too to ensure consistent T field.
+ # Note: modifyT is called after receiving unmodified T from CCPLR.
+ # If T is modified before sending, ECPLR's T will lose sharp feature.
+ # CCPLR has to call modifyT too to ensure consistent T field.
self.modifyT(self.globalBBox)
return
def preVSolverRun(self):
+ # apply bc before solving the velocity
self.applyBoundaryConditions()
return
def newStep(self):
if self.inventory.two_way_communication:
- if self.catchup:
- # send temperture field to CGE
+ if self.synchronized:
+ # send temperture field to CCPLR
for ii in self.II:
ii.send()
@@ -210,8 +221,8 @@
self.BC.impose()
- # applyBC only when previous step is a catchup step
- if self.catchup:
+ # applyBC only when previous step is sync'd
+ if self.synchronized:
self.toApplyBC = True
return
@@ -219,30 +230,31 @@
def stableTimestep(self, dt):
from ExchangerLib import exchangeTimestep
- if self.catchup:
+ if self.synchronized:
mycomm = self.communicator
- self.cge_t = exchangeTimestep(dt,
+ self.ccplr_t = exchangeTimestep(dt,
mycomm.handle(),
self.sinkComm.handle(),
0)
- self.fge_t = 0
- self.catchup = False
+ self.ecplr_t = 0
+ self.synchronized = False
- self.fge_t += dt
+ self.ecplr_t += dt
old_dt = dt
- if self.fge_t >= self.cge_t:
- dt = dt - (self.fge_t - self.cge_t)
- self.fge_t = self.cge_t
- self.catchup = True
- #print "FGE: CATCHUP!"
+ # clipping oversized ecplr_t
+ if self.ecplr_t >= self.ccplr_t:
+ dt = dt - (self.ecplr_t - self.ccplr_t)
+ self.ecplr_t = self.ccplr_t
+ self.synchronized = True
+ #print "ECPLR: SYNCHRONIZED!"
# store timestep for interpolating boundary velocities
- self.BC.storeTimestep(self.fge_t, self.cge_t)
+ self.BC.storeTimestep(self.ecplr_t, self.ccplr_t)
#print "%s - old dt = %g exchanged dt = %g" % (
# self.__class__, old_dt, dt)
- #print "cge_t = %g fge_t = %g" % (self.cge_t, self.fge_t)
+ #print "ccplr_t = %g ecplr_t = %g" % (self.ccplr_t, self.ecplr_t)
return dt
@@ -261,11 +273,11 @@
import pyre.inventory as prop
+ # excluding nodes in top boundary? (used if vbc is read from file)
+ excludeTop = prop.bool("excludeTop", default=False)
-
- excludeTop = prop.bool("excludeTop", default=False)
+ # excluding nodes in bottom boundary?
excludeBottom = prop.bool("excludeBottom", default=False)
- incompressibility = prop.bool("incompressibility", default=True)
Modified: mc/3D/CitcomS/trunk/CitcomS/Layout.py
===================================================================
--- mc/3D/CitcomS/trunk/CitcomS/Layout.py 2007-06-26 20:32:09 UTC (rev 7529)
+++ mc/3D/CitcomS/trunk/CitcomS/Layout.py 2007-06-27 01:04:41 UTC (rev 7530)
@@ -58,6 +58,8 @@
def discover(self):
+ '''Find the size/rank of the whole application.
+ '''
import mpi
self.comm = mpi.world()
self.rank = self.comm.rank
@@ -83,19 +85,24 @@
def createCommunicators(self):
+ '''Create various communicators for solvers and couplers
+ '''
world = self.comm
myrank = world.rank
ccommGroup = self.inventory.ccomm
ecommGroup = self.inventory.ecomm
- # communicator for solvers
+ # Communicator for solvers
self.ccomm = world.include(ccommGroup)
self.ecomm = world.include(ecommGroup)
- # communicator for inter-solver communication
+ # Communicator for inter-solver communication
+ # Each node in ccommGroup will form a communicator
+ # with the nodes in ecommGroup
for node in ccommGroup:
self.ecommPlus.append(world.include(ecommGroup + [node]))
+ # Ditto for each node ccommGroup
for node in ecommGroup:
self.ccommPlus.append(world.include(ccommGroup + [node]))
@@ -107,7 +114,10 @@
import pyre.inventory
+ # The containing solver will run on these nodes
ccomm = pyre.inventory.slice("ccomm", default=range(12))
+
+ # The embedded solver will run on these nodes
ecomm = pyre.inventory.slice("ecomm", default=[12])
Modified: mc/3D/CitcomS/trunk/CitcomS/SimpleApp.py
===================================================================
--- mc/3D/CitcomS/trunk/CitcomS/SimpleApp.py 2007-06-26 20:32:09 UTC (rev 7529)
+++ mc/3D/CitcomS/trunk/CitcomS/SimpleApp.py 2007-06-27 01:04:41 UTC (rev 7530)
@@ -44,7 +44,8 @@
def getNodes(self):
- # compute the required # of processors for MPI
+ '''Compute the required # of processors for MPI.
+ '''
s = self.inventory.solver.inventory.mesher.inventory
nproc = s.nproc_surf * s.nprocx * s.nprocy * s.nprocz
return nproc
@@ -52,6 +53,8 @@
def initialize(self):
+ '''Setup the problem.
+ '''
self.findLayout()
self.controller.initialize(self)
@@ -60,6 +63,8 @@
def findLayout(self):
+ '''Assign controller/solver/communicator to this process.
+ '''
self.controller = self.inventory.controller
self.solver = self.inventory.solver
import mpi
@@ -98,6 +103,10 @@
import Solver
controller = pyre.inventory.facility("controller", factory=Controller.controller)
+
+ # solver can be either "regional" (component name for Solver.regionalSolver,
+ # defined in ../etc/regional.odb) or "full" (component name for
+ # Solver.fullSolver, defined in ../etc/full.odb)
solver = pyre.inventory.facility("solver", factory=Solver.regionalSolver)
Modified: mc/3D/CitcomS/trunk/CitcomS/Solver/CoupledSolver.py
===================================================================
--- mc/3D/CitcomS/trunk/CitcomS/Solver/CoupledSolver.py 2007-06-26 20:32:09 UTC (rev 7529)
+++ mc/3D/CitcomS/trunk/CitcomS/Solver/CoupledSolver.py 2007-06-27 01:04:41 UTC (rev 7530)
@@ -44,9 +44,7 @@
def initialize(self, application):
- print self.name, 'enter initialize'
Solver.initialize(self, application)
- print self.name, self.all_variables
self.coupler = application.coupler
self.myPlus = application.myPlus
@@ -56,12 +54,10 @@
self.ic_initTemperature = self.inventory.ic.initTemperature
self.coupler.initialize(self)
- print self.name, 'exit initialize'
return
def launch(self, application):
- print self.name, 'enter launch'
self._setup()
self.coupler.launch(self)
@@ -75,12 +71,12 @@
ic.launch()
self.solveVelocities()
- print self.name, 'exit launch'
return
def solveVelocities(self):
+ # sync boundary conditions before/after vsolver
vsolver = self.inventory.vsolver
self.coupler.preVSolverRun()
vsolver.run()
@@ -89,8 +85,8 @@
- def solveAdditional(self):
- # override Solver.solveAdditional, since tracer module
+ def advectTracers(self):
+ # override Solver.advectTracers to do nothing, since tracer module
# doesn't work in coupled run
return
@@ -98,6 +94,8 @@
def newStep(self):
Solver.newStep(self)
+
+ # sync the temperature field
self.coupler.newStep()
return
More information about the cig-commits
mailing list