ReikaKalseki / Reika_Mods_Issues

The issue tracker for all of my mods - RotaryCraft, its addons, ChromatiCraft, and everything else.
46 stars 13 forks source link

High Pressure Turbine Fluid Loss #114

Closed Fatmice closed 9 years ago

Fatmice commented 9 years ago

I've been at a loss as to why I can not make close loops with high pressure turbine . Closer inspection of the code seems to point the problem to these line (162-166)

FluidStack fs = new FluidStack(fluid.getLowPressureFluid(), TileEntityReactorBoiler.WATER_PER_STEAM/12);
if (m == MachineRegistry.RESERVOIR) {
    TileEntity te = this.getTileEntity(tx, ty, tz);
    ((TileEntityReservoir)te).addLiquid(fs.amount, fs.getFluid());
}

Since 1 steam = 200 units of water, the above code only dump 16.6 units low pressure water into the Reservoir. Unless I'm reading this code wrong, this is a significant loss. Ammonia loop with this sort of loss is unfeasible.

It seems another person had reported this issue on the MFC thread here, and here.

Contrary to the fluid loss encountered through HP Turbine, I've been able to setup close loop using the LP Turbine with minimal loss. There is still some loss over time, but the amount is very small, about 2600 mB per hour per LP Turbine. The reason for this loss overtime is unknown to me since steam block touching a condenser is converted to 200 units of low pressure fluid, which is exactly the amount of normal fluid used to make a unit of steam.

ReikaKalseki commented 9 years ago

Fluid output is spread across the entire width, and you can use two whole lines of reservoirs across it. Each reservoir only gets a fraction. Hence the /12.

Fatmice commented 9 years ago

I wouldn't be so fast as to describe this as a "User Error." 3lines

I place a reservoir where fluid could be dumped. It's actually 11 blocks, 3 deep. The steel blocks are there, only for the screenshot, to give indication of where the reservoirs are with relation to the last HP Turbine core above it.

How's that divided/12? Please have a look again.

ReikaKalseki commented 9 years ago

Each reservoir - independently of all others - receives 1/12 of "WATER_PER_STEAM" every tick, meaning if you have 12 reservoirs, you have 100% (or close to it) reclamation.

Fatmice commented 9 years ago

So having more than 12 reservoirs below, 33 from the count of that screenshot, shouldn't be the source of the loss no?

Since fluid can not be fractional, the 2/3 of a unit from 200/12 is lost. It is not due to steam being stuck in the steam pipes either as I maintained no more than 300 units by use of steam grate to bleed steam to the condenser as needed to keep a constant number. A pipe pump made sure all steam produced is immediately pumped to the turbine.. The HP Turbine uses approximately 84 units of steam per second, so that's only a loss of 56 units of liquid...This does not explain the incredible loss in the close loop of 10-20 buckets/s

ReikaKalseki commented 9 years ago

So having more than 12 reservoirs below, 33 from the count of that screenshot, shouldn't be the source of the loss no?

No, that would in fact give you more than you put in.

The HP Turbine uses approximately 84 units of steam per second

This may be the real source of the issue. At 84 blocks a second, it would be voiding 50% of the steam going in (since only ~40 blocks/s can be pumped out into 24 reservoirs). Are you sure it uses that much?

Fatmice commented 9 years ago

Okay, I tested this over 5 min.

Starting steam level (2 steam pipes) => (20066 + 20068) = 40134 (8,026,800 units of liquid) Ending steam level (2 steam pipes) => (3102 + 3103) = 6205 (1,241,000 units of liquid) Recovered = 2,232,864 units of liquid

Steam usage => (40134 - 6025) / (5 * 60 s) = 113.69 ~ 113 steam / s Gross Liquid loss => (8026800 - 1241000) / (5 * 60s) = 22619.33 ~ 22 buckets / s Net Liquid loss => (8026800 - 1241000 - 2232864) / (5 * 60s) = 15176.45 ~ 15 buckets / s

2232864 / (8026800 - 1241000) => 32.90 % Liquid Recovered or 67.09 % Liquid Loss

(113 - 40) / 113 => 65% steam loss!

So the numbers I've used in the previous postings are quite on the ball.

==Starting steam lvl== 2015-06-27_18 24 00

==Ending steam lvl== 2015-06-27_18 31 14

==Recovered liquid== 2015-06-27_18 32 08

Fatmice commented 9 years ago

Here's the results of a 30 min run.

Starting steam level (2 steam pipes) => (250117+250116) = 500233 (100,064,400 units of liquid) Ending steam level (2 steam pipes) => (156641+156640) = 313281 (62,656,200 units of liquid) Recovered = 10,873,728 units of liquid

Steam usage => (500233 - 313281) / (30 * 60 s) = 103.86 ~ 103 steam / s Gross Liquid loss => (100064400 - 62656200) / (30 * 60s) = 20782.33 ~ 20 buckets / s Net Liquid loss => (100064400 - 62656200 - 10873728) / (30 * 60s) = 14741.37 ~ 15 buckets / s

10873728 / (100064400 - 62656200) => 29.06% Liquid Recovered or 70.93% Liquid Loss

[(103 - 40) / 103] => 60% steam loss!

So this is already a good convergence and any longer run time would not converge much further.

ReikaKalseki commented 9 years ago

It sounds like the fix, then, is to add another multiplier, the steam usage per tick (~5.13).

Fatmice commented 9 years ago

Here's the results of a 30 min run for v7a

Starting steam level (2 steam pipes) => (1084335+1084333) = 2168668 (433,733,600 units of liquid) Ending steam level (2 steam pipes) => (991410+991408) = 1982818 (396,563,600 units of liquid) Recovered = 28,530,684 units of liquid

Steam usage => (2168668 - 1982818) / (30 * 60s) = 103.25 ~ 103 steam / s Gross Liquid loss => (433733600 - 396563600) / (30 * 60s) = 20650 ~ 20 buckets / s Net Liquid loss => (433733600 - 396563600 - 28530684) / (30 * 60s) = 4799.62 ~ 5 buckets / s

(28530684) / (433733600 - 396563600) => 76.75% Liquid Recovered or 23.24% Liquid Loss

The hemorrhage is better controlled, but still not completely plugged.

The 5.15x mutliplier reduced loss from 70.93% -> 23.24% => 3.05x If proportionality applies, then to reduce loss further maybe try a multiplier of 24x => 103/4.3

int amt = TileEntityReactorBoiler.WATER_PER_STEAM*103/4.3/24;

ReikaKalseki commented 9 years ago

Done.

ReikaKalseki commented 9 years ago

zemerick says the new ratios cause an exploit. http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/1291655-reikas-mods-tech-worldgen-civilization-and-more?comment=21886

Fatmice commented 9 years ago

Yep, it generated 3.60x more liquid than it used. I just tested myself. Maybe the multiplier can not be scaled proportionally.

Test showed it recovered 135,216,884 units of liquid for 37,390,400 units of liquid consumed.

Reika, how do you setup your dev environment in eclipse ? I heard you have a nightmare of dependencies...I need to either compile your source or learn to ASM the compiled jar to test a new multiplier.

ReikaKalseki commented 9 years ago

Well, you could change this reflectively. It is stored in a public static final int now.

Fatmice commented 9 years ago

I don't know enough java to do reflection yet, but I'm trying. It seems setting up an eclipse environment to do forge modding is not so easy. Bytecode editing your classes is a no go since that changes the sha-256 digest and DragonAPI refuses to load...

Anyways, short of being able to reflect the variable FLUID_PER_RESERVOIR yet, I looked at the numbers more closely. It would seems the increase in recovery is proportional after all!

For v6f

When there was no multiplier, the amount of liquid coded to dump into a reservoir was 16/reservoir/tick. The expected liquid recovered from steam after 1800s was supposed to be 13,824,000 whereas the actual amount recovered was 10,873,728.

10,873,728 / 13,824,000 = 78.65% of expected

For v7a

When the multiplier was 103/20, the amount of liquid coded to dump into a reservoir was 42/reservoir/tick. The expected liquid recovered from steam after 1800s was supposed to be 36,288,000 whereas the actual amount recovered was 28,530,684.

28,530,684 / 36,288,000 = 78.62% of expected

For v7b

When the multiplier was 1030/43, the amount of liquid coded to dump into a reservoir was 199/reservoir/tick. The expected liquid recovered from steam after 1800s was supposed to be 171,936,000 whereas the actual amount recovered was 135,216,884.

135,216,884 / 171,936,000 = 78.64% of expected

So!

Regardless of the multiplier used, the actual amount recovered seems to always be 78.6% of the expected amount. Given that, it would seems logical that the multiplier to use to compensate for the 21.4% or so discrepancy is inv(.786)*5.15 = 6.55 => 131/20

public static final int FLUID_PER_RESERVOIR = TileEntityReactorBoiler.WATER_PER_STEAM*131/20/24

This is equivalent to 54/reservoir/tick. The expected recovery after 1800s is 46,656,000 and the projected actual amount recovered is 36,671,616. Given that steam is consumed at 103/s, the liquid consumed in 1800s is 37,080,000. Therefore, if everything is as it should be (pray), then 36,671,616 / 37,080,000 = 98.8% liquid recovery.

If only bytecode editing your class would work...I can test immediately and feel better about this. Why did you have to enforce verifyHash()?

ReikaKalseki commented 9 years ago

Hash verification was put in because I caught a couple modpacks inserting malware.

I implemented the new ratios.

Fatmice commented 9 years ago

v7c Starting steam level (2 steam pipes) => (1187605 + 1187604) = 2375209 (475,041,800 units of liquid) Ending steam level (2 steam pipes) => (1094128 + 1094128) = 2188257 (437,651,400 units of liquid) Recovered = 36,688,140 units of liquid

Steam usage => (2375209 - 2188257 ) / (30 * 60 s) = 103.86 ~ 103 steam / s Gross Liquid loss => (475041800 - 437651400) / (30 * 60s) = 20772.44 ~ 20 buckets / s Net Liquid loss => (475041800 - 437651400 - 36688140) / (30 * 60) = 390.14 ~ 0.4 buckets / s

(36688140) / (475041800 - 437651400) => 98.12% Liquid Recovered or 1.88% Liquid Loss

We have a winner! My calculation is spot on this time. =)

When you feel like it,

public static final int FLUID_PER_RESERVOIR = TileEntityReactorBoiler.WATER_PER_STEAM*132/20/24

That will give 55/reservoir/tick => The effective loss should be 0.1% or a loss of 21 mB/HPT/s => 78 buckets/HPT/hour This is a close as it can get without spawning more liquid than it consumed.