def _resetWorker(self): """ Clear out the reactor on the workers to start anew. Notes ----- This was made to help minimize the amount of RAM that is used during some gigantic long-running cases. Resetting after building copies of reactors or transforming their geometry is one approach. We hope to implement more efficient solutions in the future. .. warning:: This should build empty non-core systems too. """ xsGroups = self.getInterface("xsGroups") if xsGroups: xsGroups.clearRepresentativeBlocks() cs = settings.getMasterCs() bp = self.r.blueprints spatialGrid = self.r.core.spatialGrid self.detach() self.r = reactors.Reactor(cs.caseTitle, bp) core = reactors.Core("Core") self.r.add(core) core.spatialGrid = spatialGrid self.reattach(self.r, cs)
def getEmptyHexReactor(cs=None): """Make an empty hex reactor used in some tests.""" cs = cs or settings.getMasterCs() bp = blueprints.Blueprints() reactor = reactors.Reactor(cs, bp) reactor.add(reactors.Core("Core", cs)) reactor.core.spatialGrid = grids.hexGridFromPitch(1.0) reactor.core.spatialGrid.symmetry = geometry.THIRD_CORE + geometry.PERIODIC reactor.core.spatialGrid.geomType = geometry.HEX reactor.core.spatialGrid.armiObject = reactor.core return reactor
def getEmptyHexReactor(): """Make an empty hex reactor used in some tests.""" from armi.reactor import blueprints bp = blueprints.Blueprints() reactor = reactors.Reactor("Reactor", bp) reactor.add(reactors.Core("Core")) reactor.core.spatialGrid = grids.hexGridFromPitch(1.0) reactor.core.spatialGrid.symmetry = geometry.THIRD_CORE + geometry.PERIODIC reactor.core.spatialGrid.geomType = geometry.HEX reactor.core.spatialGrid.armiObject = reactor.core return reactor
def setUp(self): bp = blueprints.Blueprints() r = reactors.Reactor(settings.getMasterCs(), bp) r.add(reactors.Core("Core", settings.getMasterCs())) r.core.spatialGrid = grids.hexGridFromPitch(1.0) r.core.spatialGrid.symmetry = geometry.THIRD_CORE + geometry.PERIODIC r.core.spatialGrid.geomType = geometry.HEX aList = [] for ring in range(10): a = assemblies.HexAssembly("fuel") a.spatialLocator = r.core.spatialGrid[ring, 1, 0] a.parent = r.core aList.append(a) self.aList = aList
def setUp(self): bp = blueprints.Blueprints() geom = geometry.SystemLayoutInput() geom.symmetry = "third core periodic" r = reactors.Reactor(settings.getMasterCs(), bp) r.add(reactors.Core("Core", settings.getMasterCs(), geom)) r.core.spatialGrid = grids.hexGridFromPitch(1.0) aList = [] for ring in range(10): a = assemblies.HexAssembly("fuel") a.spatialLocator = r.core.spatialGrid[ring, 1, 0] a.parent = r.core aList.append(a) self.aList = aList
def getEmptyCartesianReactor(): """Return an empty Cartesian reactor used in some tests.""" from armi.reactor import blueprints bp = blueprints.Blueprints() reactor = reactors.Reactor("Reactor", bp) reactor.add(reactors.Core("Core")) reactor.core.spatialGrid = grids.CartesianGrid.fromRectangle(1.0, 1.0) reactor.core.spatialGrid.symmetry = ( geometry.QUARTER_CORE + geometry.REFLECTIVE + geometry.THROUGH_CENTER_ASSEMBLY ) reactor.core.spatialGrid.geomType = geometry.CARTESIAN reactor.core.spatialGrid.armiObject = reactor.core return reactor
def setUp(self): bp = blueprints.Blueprints() r = reactors.Reactor("zonetest", bp) r.add(reactors.Core("Core")) r.core.spatialGrid = grids.HexGrid.fromPitch(1.0) r.core.spatialGrid.symmetry = geometry.SymmetryType( geometry.DomainType.THIRD_CORE, geometry.BoundaryType.PERIODIC) r.core.spatialGrid.geomType = geometry.HEX aList = [] for ring in range(10): a = assemblies.HexAssembly("fuel") a.spatialLocator = r.core.spatialGrid[ring, 1, 0] a.parent = r.core aList.append(a) self.aList = aList
def getEmptyCartesianReactor(pitch=(10.0, 16.0)): """Return an empty Cartesian reactor used in some tests.""" from armi.reactor import blueprints bp = blueprints.Blueprints() reactor = reactors.Reactor("Reactor", bp) reactor.add(reactors.Core("Core")) reactor.core.spatialGrid = grids.CartesianGrid.fromRectangle(*pitch) reactor.core.spatialGrid.symmetry = geometry.SymmetryType( geometry.DomainType.QUARTER_CORE, geometry.BoundaryType.REFLECTIVE, throughCenterAssembly=True, ) reactor.core.spatialGrid.geomType = geometry.CARTESIAN reactor.core.spatialGrid.armiObject = reactor.core return reactor
def createDummyReactor(): """ Create a dummy reactor with a single fuel assembly and a single fuel block. Often, a reactor model like this is built directly from input files rather than from code as done here. """ bp = blueprints.Blueprints() cs = settings.Settings() r = reactors.Reactor("Reactor", bp) r.add(reactors.Core("Core")) r.core.spatialGrid = grids.HexGrid.fromPitch(1.0) r.core.spatialGrid.symmetry = geometry.SymmetryType( geometry.DomainType.THIRD_CORE, geometry.BoundaryType.PERIODIC) r.core.spatialGrid.geomType = geometry.GeomType.HEX r.core.spatialGrid.armiObject = r.core r.core.setOptionsFromCs(cs) # Create a single fuel assembly a = assemblies.HexAssembly("fuel assembly") a.spatialGrid = grids.axialUnitGrid(1) a.spatialLocator = r.core.spatialGrid[1, 0, 0] # Create a single fuel block b = blocks.HexBlock("fuel block") b.setType("fuel") # Create a single fuel component with UZr fuel. dims = {"Tinput": 20, "Thot": 900, "id": 0.0, "od": 2.9, "mult": 7} c = Circle("fuel", uZr.UZr(), **dims) b.add(c) # Create a single structure component with HT9. dims = {"Tinput": 20, "Thot": 600, "op": 16.0, "ip": 15.0, "mult": 1} c = Hexagon("structure", ht9.HT9(), **dims) b.add(c) # Fill in the rest of the block with sodium coolant. dims = {"Tinput": 600, "Thot": 600} c = DerivedShape("coolant", sodium.Sodium(), **dims) b.add(c) a.add(b) r.core.add(a) _addFlux(b) return r
def _setupReactor(self): fnames = [ self._testMethodName + n for n in ["geometry.xml", "sfp-geom.xml"] ] for fn in fnames: with open(fn, "w") as f: f.write(GEOM) cs = settings.Settings() cs["geomFile"] = self._testMethodName + "geometry.xml" bp = blueprints.Blueprints.load( test_customIsotopics.TestCustomIsotopics.yamlString) bp.systemDesigns = self.systemDesigns reactor = reactors.Reactor(cs, bp) core = bp.systemDesigns["core"].construct(cs, bp, reactor) sfp = bp.systemDesigns["sfp"].construct(cs, bp, reactor) for fn in fnames: os.remove(fn) return core, sfp
def _setupReactor(self): fnames = [ self._testMethodName + n for n in ["geometry.xml", "sfp-geom.xml"] ] for fn in fnames: with open(fn, "w") as f: f.write(GEOM) # test migration from geometry xml files cs = settings.Settings() newSettings = {"geomFile": self._testMethodName + "geometry.xml"} cs = cs.modified(newSettings=newSettings) bp = blueprints.Blueprints.load( test_customIsotopics.TestCustomIsotopics.yamlString) bp.systemDesigns = self.systemDesigns bp.gridDesigns = self.gridDesigns reactor = reactors.Reactor(cs.caseTitle, bp) core = bp.systemDesigns["core"].construct(cs, bp, reactor) sfp = bp.systemDesigns["sfp"].construct(cs, bp, reactor) for fn in fnames: os.remove(fn) return core, sfp
def workerOperate(self): """ The main loop on any worker MPI nodes. Notes ----- This method is what worker nodes are in while they wait for instructions from the master node in a parallel run. The nodes will sit, waiting for a "worker command". When this comes (from a bcast from the master), a set of if statements are evaluated, with specific behaviors defined for each command. If the operator doesn't understand the command, it loops through the interface stack to see if any of the interfaces understand it. Originally, "magic strings" were broadcast, which were handled either here or in one of the interfaces' ``workerOperate`` methods. Since then, the :py:mod:`~armi.mpiActions` system has been devised which just broadcasts ``MpiAction`` objects. Both methods are still supported. See Also -------- armi.mpiActions : MpiAction information armi.interfaces.workerOperate : interface-level handling of worker commands. """ while True: # sit around waiting for a command from the master runLog.extra("Node {0} ready and waiting".format(armi.MPI_RANK)) cmd = armi.MPI_COMM.bcast(None, root=0) runLog.extra("worker received command {0}".format(cmd)) # got a command. go use it. if isinstance(cmd, mpiActions.MpiAction): cmd.invoke(self, self.r, self.cs) elif cmd == "quit": self.workerQuit() break # If this break is removed, the program will remain in the while loop forever. elif cmd == "finished": runLog.warning( "Received unexpected FINISHED command. Usually a QUIT command precedes this. " "Skipping cleanup of temporary files.") break elif cmd == "sync": # wait around for a sync runLog.debug("Worker syncing") note = armi.MPI_COMM.bcast("wait", root=0) if note != "wait": raise RuntimeError( 'did not get "wait". Got {0}'.format(note)) else: # we don't understand the command on our own. check the interfaces # this allows all interfaces to have their own custom operation code. handled = False for i in self.interfaces: handled = i.workerOperate(cmd) if handled: break if not handled: if armi.MPI_RANK == 0: print("Interfaces" + str(self.interfaces)) runLog.error( "No interface understood worker command {0}\n check stdout for err\n" "available interfaces:\n {1}".format( cmd, "\n ".join("name:{} typeName:{} {}".format( i.name, i.function, i) for i in self.interfaces), )) raise RuntimeError( "Failed to delegate worker command {} to an interface." .format(cmd)) if self._workersShouldResetAfter(cmd): # clear out the reactor on the workers to start anew. # Note: This should build empty non-core systems too. xsGroups = self.getInterface("xsGroups") if xsGroups: xsGroups.clearRepresentativeBlocks() cs = settings.getMasterCs() bp = self.r.blueprints spatialGrid = self.r.core.spatialGrid self.detach() self.r = reactors.Reactor(cs, bp) core = reactors.Core("Core", cs) self.r.add(core) core.spatialGrid = spatialGrid self.reattach(self.r, cs) # might be an mpi action which has a reactor and everything, preventing # garbage collection del cmd gc.collect()
def setUp(self): self.cs = settings.Settings() newSettings = {"xsKernel": "MC2v2"} # don't try to expand elementals self.cs = self.cs.modified(newSettings=newSettings) settings.setMasterCs(self.cs) bp = blueprints.Blueprints() self.r = reactors.Reactor("test", bp) self.r.add(reactors.Core("Core")) inputStr = """blocks: ann fuel: &block_ann_fuel gap: shape: Circle material: Void Tinput: 20.0 Thot: 435.0 id: 0.0 mult: fuel.mult od: fuel.id fuel: shape: Circle material: UZr Tinput: 20.0 Thot: 600.0 id: 0.1 mult: 127 od: 0.8 gap1: shape: Circle material: Void Tinput: 20.0 Thot: 435.0 id: fuel.od mult: fuel.mult od: clad.id clad: shape: Circle material: HT9 Tinput: 20.0 Thot: 435.0 id: .85 mult: fuel.mult od: .95 duct: &component_type2_fuel_duct shape: Hexagon material: HT9 Tinput: 20.0 Thot: 435.0 ip: 13.00 op: 13.9 mult: 1 intercoolant: &component_type2_fuel_intercoolant shape: Hexagon material: Sodium Tinput: 435.0 Thot: 435.0 ip: duct.op mult: 1 op: 16 coolant: &component_type2_fuel_coolant shape: DerivedShape material: Sodium Tinput: 435.0 Thot: 435.0 assemblies: heights: &standard_heights [30.0] axial mesh points: &standard_axial_mesh_points [2] ann fuel: specifier: FA blocks: &inner_igniter_fuel_blocks [*block_ann_fuel] height: *standard_heights axial mesh points: *standard_axial_mesh_points hotChannelFactors: TWRPclad xs types: &inner_igniter_fuel_xs_types [D] """ self.blueprints = blueprints.Blueprints.load(inputStr) self.blueprints._prepConstruction(self.cs)