Reactor Logic work. More complex now, and more realistic, taking some cues from BigReactors' example.

Plasma conducts temperature to the casing, which then conducts to coolant or the environment. Energy from passive cooling is stored in an internal buffer.
This commit is contained in:
Ben Spiers 2014-07-16 02:53:32 +01:00
parent 62659afadb
commit 8673440172
2 changed files with 75 additions and 38 deletions

View file

@ -46,20 +46,31 @@ public class FusionReactor implements IFusionReactor
public Set<IReactorBlock> reactorBlocks = new HashSet<IReactorBlock>(); public Set<IReactorBlock> reactorBlocks = new HashSet<IReactorBlock>();
public Set<INeutronCapture> neutronCaptors = new HashSet<INeutronCapture>(); public Set<INeutronCapture> neutronCaptors = new HashSet<INeutronCapture>();
public double temperature; //Current stores of energy
public static double burnTemperature = 1E8; public double plasmaTemperature;
public double caseTemperature;
public double energyBuffer;
//Reaction characteristics
public static double burnTemperature = 1E8;
public static double burnRatio = 1; public static double burnRatio = 1;
public static double tempPerFuel = 5E6; public static double tempPerFuel = 5E6;
public int injectionRate = 0; public int injectionRate = 0;
public static double coolingCoefficient = 0.1; //Thermal characteristics
public static double plasmaHeatCapacity = 1;
public static double waterRatio = 1E-14; public static double caseHeatCapacity = 1;
public static double inverseHeatCapacity = 1; public static double enthalpyOfVaporization = 10;
public static double thermocoupleEfficiency = 0.01;
//Heat transfer metrics
public static double plasmaCaseConductivity = 0.2;
public static double caseWaterConductivity = 0.3;
public static double caseAirConductivity = 0.1;
public boolean burning = false; public boolean burning = false;
public boolean hasHohlraum = false; public boolean hasHohlraum = false;
public boolean activelyCooled = true;
public boolean formed = false; public boolean formed = false;
@ -71,35 +82,45 @@ public class FusionReactor implements IFusionReactor
@Override @Override
public void addTemperatureFromEnergyInput(double energyAdded) public void addTemperatureFromEnergyInput(double energyAdded)
{ {
temperature += energyAdded * inverseHeatCapacity; plasmaTemperature += energyAdded / plasmaHeatCapacity;
} }
@Override @Override
public void simulate() public void simulate()
{ {
if(temperature >= burnTemperature) //Only thermal transfer happens unless we're hot enough to burn.
if(plasmaTemperature >= burnTemperature)
{ {
//If we're not burning yet we need a hohlraum to ignite
if(!burning && hasHohlraum) if(!burning && hasHohlraum)
{ {
vaporiseHohlraum(); vaporiseHohlraum();
} }
injectFuel(); //Only inject fuel if we're burning
if(burning)
{
injectFuel();
int fuelBurned = burnFuel(); int fuelBurned = burnFuel();
neutronFlux(fuelBurned); neutronFlux(fuelBurned);
}
} }
else { else {
burning = false; burning = false;
} }
boilWater();
ambientLoss(); //Perform the heat transfer calculations
if(temperature > 0) transferHeat();
Mekanism.logger.info("Reactor temperature: " + (int)temperature);
if(plasmaTemperature > 1E-6 || caseTemperature > 1E-6)
{
Mekanism.logger.info("Reactor temperatures: Plasma: " + (int) plasmaTemperature + ", Casing: " + (int) caseTemperature);
}
} }
public void vaporiseHohlraum() public void vaporiseHohlraum()
{ {
fuelTank.receive(new GasStack(GasRegistry.getGas("fusionFuelDT"), 1000), true); fuelTank.receive(new GasStack(GasRegistry.getGas("fusionFuelDT"), 10), true);
hasHohlraum = false; hasHohlraum = false;
burning = true; burning = true;
} }
@ -117,9 +138,9 @@ public class FusionReactor implements IFusionReactor
public int burnFuel() public int burnFuel()
{ {
int fuelBurned = (int)min(fuelTank.getStored(), max(0, temperature-burnTemperature)*burnRatio); int fuelBurned = (int)min(fuelTank.getStored(), max(0, plasmaTemperature - burnTemperature)*burnRatio);
fuelTank.draw(fuelBurned, true); fuelTank.draw(fuelBurned, true);
temperature += tempPerFuel * fuelBurned; plasmaTemperature += tempPerFuel * fuelBurned;
return fuelBurned; return fuelBurned;
} }
@ -138,21 +159,34 @@ public class FusionReactor implements IFusionReactor
controller.radiateNeutrons(neutronsRemaining); controller.radiateNeutrons(neutronsRemaining);
} }
public void boilWater() public void transferHeat()
{ {
int waterToBoil = (int)min(waterTank.getFluidAmount(), temperature*1E-6); //Transfer from plasma to casing
int steamToGenerate = (int)(waterToBoil*temperature * 1E-6); double plasmaCaseHeat = plasmaCaseConductivity * (plasmaTemperature - caseTemperature);
waterTank.drain(waterToBoil, true); plasmaTemperature -= plasmaCaseHeat / plasmaHeatCapacity;
steamTank.fill(new FluidStack(FluidRegistry.getFluid("steam"), steamToGenerate), true); caseTemperature += plasmaCaseHeat / caseHeatCapacity;
}
public void ambientLoss() //Transfer from casing to water if necessary
{ if(activelyCooled)
temperature -= coolingCoefficient*temperature;
if(temperature < 1E-6)
{ {
temperature = 0; double caseWaterHeat = caseWaterConductivity * caseTemperature;
int waterToVaporize = (int)(caseWaterHeat / enthalpyOfVaporization);
Mekanism.logger.info("Wanting to vaporise " + waterToVaporize + "mB of water");
waterToVaporize = min(waterToVaporize, min(waterTank.getFluidAmount(), steamTank.getCapacity() - steamTank.getFluidAmount()));
if(waterToVaporize > 0)
{
Mekanism.logger.info("Vaporising " + waterToVaporize + "mB of water");
waterTank.drain(waterToVaporize, true);
steamTank.fill(new FluidStack(FluidRegistry.getFluid("steam"), waterToVaporize), true);
}
caseWaterHeat = waterToVaporize * enthalpyOfVaporization;
caseTemperature -= caseWaterHeat / caseHeatCapacity;
} }
//Transfer from casing to environment
double caseAirHeat = caseAirConductivity * caseTemperature;
caseTemperature -= caseAirHeat / caseHeatCapacity;
energyBuffer += caseAirHeat * thermocoupleEfficiency;
} }
@Override @Override
@ -191,6 +225,8 @@ public class FusionReactor implements IFusionReactor
{ {
block.setReactor(null); block.setReactor(null);
} }
//Don't remove from controller
controller.setReactor(this);
reactorBlocks.clear(); reactorBlocks.clear();
neutronCaptors.clear(); neutronCaptors.clear();
formed = false; formed = false;
@ -199,6 +235,8 @@ public class FusionReactor implements IFusionReactor
@Override @Override
public void formMultiblock() public void formMultiblock()
{ {
Mekanism.logger.trace("Attempting to form multiblock");
Coord4D controllerPosition = Coord4D.get(controller); Coord4D controllerPosition = Coord4D.get(controller);
Coord4D centreOfReactor = controllerPosition.getFromSide(ForgeDirection.DOWN, 2); Coord4D centreOfReactor = controllerPosition.getFromSide(ForgeDirection.DOWN, 2);
@ -206,28 +244,28 @@ public class FusionReactor implements IFusionReactor
reactorBlocks.add(controller); reactorBlocks.add(controller);
Mekanism.logger.info("Centre at " + centreOfReactor.toString()); Mekanism.logger.trace("Centre at " + centreOfReactor.toString());
if(!createFrame(centreOfReactor)) if(!createFrame(centreOfReactor))
{ {
unformMultiblock(); unformMultiblock();
Mekanism.logger.info("Reactor failed: Frame not complete."); Mekanism.logger.trace("Reactor failed: Frame not complete.");
return; return;
} }
Mekanism.logger.info("Frame valid"); Mekanism.logger.trace("Frame valid");
if(!addSides(centreOfReactor)) if(!addSides(centreOfReactor))
{ {
unformMultiblock(); unformMultiblock();
Mekanism.logger.info("Reactor failed: Sides not complete."); Mekanism.logger.trace("Reactor failed: Sides not complete.");
return; return;
} }
Mekanism.logger.info("Side Blocks Valid"); Mekanism.logger.trace("Side Blocks Valid");
if(!centreIsClear(centreOfReactor)) if(!centreIsClear(centreOfReactor))
{ {
unformMultiblock(); unformMultiblock();
Mekanism.logger.info("Blocks in chamber."); Mekanism.logger.trace("Blocks in chamber.");
return; return;
} }
Mekanism.logger.info("Centre is clear"); Mekanism.logger.trace("Centre is clear");
formed = true; formed = true;
} }

View file

@ -21,7 +21,6 @@ public class TileEntityReactorController extends TileEntityReactorBlock
{ {
setReactor(new FusionReactor(this)); setReactor(new FusionReactor(this));
} }
Mekanism.logger.info("Attempting to form multiblock");
getReactor().formMultiblock(); getReactor().formMultiblock();
} }