Skip to content

Commit 17c42fa

Browse files
committed
Add cryocooler support
1 parent f729f92 commit 17c42fa

9 files changed

Lines changed: 450 additions & 114 deletions

File tree

RealFuels/CryoCooler.cfg

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Cryocooler defaults for RealFuels tanks.
2+
// Refer to \RealismOverhaul\RO_RealFuels_Crycoolers.cfg for references and formulas.
3+
4+
@PART:HAS[@MODULE[ModuleFuelTanks]:HAS[#type[Cryogenic]]]:AFTER[RealFuels]
5+
{
6+
&rfAddCryocooler = true
7+
}
8+
9+
@PART:HAS[@MODULE[ModuleFuelTanks]:HAS[#type[BalloonCryo]]]:AFTER[RealFuels]
10+
{
11+
&rfAddCryocooler = true
12+
}
13+
14+
@PART:HAS[@MODULE[ModuleFuelTanks]:HAS[#type[ServiceModule]]]:AFTER[RealFuels]
15+
{
16+
&rfAddCryocooler = true
17+
}
18+
19+
@PART:HAS[#rfAddCryocooler[?rue]]:NEEDS[!RealismOverhaul]:AFTER[RealFuels]
20+
{
21+
@MODULE[ModuleFuelTanks]
22+
{
23+
maxCoolerInputKW = 10
24+
coolerBaseMass = 0.01
25+
coolerMassPerKWInput
26+
{
27+
key = 4 0.120
28+
key = 20 0.060
29+
key = 40 0.030
30+
key = 65 0.025
31+
key = 90 0.020
32+
key = 150 0.015
33+
key = 250 0.010
34+
}
35+
coolerBaseCost = 150
36+
coolerCostPerKWInput
37+
{
38+
key = 4 9000
39+
key = 20 4500
40+
key = 40 2250
41+
key = 65 1875
42+
key = 90 1500
43+
key = 150 1125
44+
key = 250 750
45+
}
46+
cryoCoolerEfficiency
47+
{
48+
key = 0 0
49+
key = 4 0.01
50+
key = 20 0.08
51+
key = 65 0.20
52+
key = 90 0.25
53+
key = 150 0.40
54+
key = 250 0.50
55+
}
56+
}
57+
}
58+
59+
// cleanup
60+
@PART:HAS[#rfAddCryocooler]:AFTER[RealFuels]
61+
{
62+
!rfAddCryocooler = delete
63+
}

RealFuels/Localization/en-us.cfg

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ Localization
181181
#RF_FuelTankRF_NoMLI = No MLI
182182
#RF_FuelTankRF_Boiloffunit = kg/hr
183183
#RF_FuelTankRF_kerbalismtips = boiloff product
184+
#RF_FuelTankRF_CryoCoolerInputPower = Cooler Input
185+
#RF_FuelTankRF_CryoCoolerLift = Cooling Lift
186+
#RF_FuelTankRF_CryoCoolerDraw = Power Draw
187+
#RF_FuelTankRF_CryoCoolerCOP = Avg COP
184188

185189
#RF_TankDefineSelection_HighlyPressurized = Highly Pressurized
186190
#RF_TankDefineSelection_NotHighlyPressurized = Not Highly Pressurized

RealFuels/Localization/pt-br.cfg

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,10 @@ Localization
177177
#RF_FuelTankRF_NoMLI = Sem MLI
178178
#RF_FuelTankRF_Boiloffunit = kg/h
179179
#RF_FuelTankRF_kerbalismtips = produto de evaporação
180+
#RF_FuelTankRF_CryoCoolerInputPower = Cooler Input
181+
#RF_FuelTankRF_CryoCoolerLift = Cooling Lift
182+
#RF_FuelTankRF_CryoCoolerDraw = Power Draw
183+
#RF_FuelTankRF_CryoCoolerCOP = Avg COP
180184

181185
#RF_TankDefineSelection_HighlyPressurized = Altamente Pressurizado
182186
#RF_TankDefineSelection_NotHighlyPressurized = Não Altamente Pressurizado

RealFuels/Localization/ru.cfg

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,10 @@ Localization
177177
#RF_FuelTankRF_NoMLI = Без ЭВТИ
178178
#RF_FuelTankRF_Boiloffunit = кг/ч
179179
#RF_FuelTankRF_kerbalismtips = резальтат испарения
180+
#RF_FuelTankRF_CryoCoolerInputPower = Cooler Input
181+
#RF_FuelTankRF_CryoCoolerLift = Cooling Lift
182+
#RF_FuelTankRF_CryoCoolerDraw = Power Draw
183+
#RF_FuelTankRF_CryoCoolerCOP = Avg COP
180184

181185
#RF_TankDefineSelection_HighlyPressurized = Бак высокого давления
182186
#RF_TankDefineSelection_NotHighlyPressurized = Бак нормальн. давления

RealFuels/Localization/zh-cn.cfg

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,10 @@ Localization
177177
#RF_FuelTankRF_NoMLI = 无隔热层
178178
#RF_FuelTankRF_Boiloffunit = 千克/时
179179
#RF_FuelTankRF_kerbalismtips = 蒸发产出
180+
#RF_FuelTankRF_CryoCoolerInputPower = Cooler Input
181+
#RF_FuelTankRF_CryoCoolerLift = Cooling Lift
182+
#RF_FuelTankRF_CryoCoolerDraw = Power Draw
183+
#RF_FuelTankRF_CryoCoolerCOP = Avg COP
180184

181185
#RF_TankDefineSelection_HighlyPressurized = 高压
182186
#RF_TankDefineSelection_NotHighlyPressurized = 非高压

RealFuels/MFSSettings.cfg

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ MFSSETTINGS
55
BatteryMultiplier = 1
66

77
basemassUseTotalVolume = True
8-
9-
radiatorMinTempMult = 0.99
10-
8+
119
IgnoreFuelsForFill
1210
{
1311
IntakeAir = True

Source/Tanks/BgBoiloffCache.cs

Lines changed: 91 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,105 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Globalization;
4+
15
namespace RealFuels.Tanks
26
{
37
internal sealed class BgBoiloffCache
48
{
5-
internal readonly string DataVersion;
69
internal readonly int MliLayers;
710
internal readonly BgTankEntry[] Tanks;
8-
internal readonly double[] InternalTemps; // mutable, parallel to Tanks; -1 = uninitialized
11+
internal readonly double[] InternalTemps; // mutable, parallel to Tanks
12+
internal readonly double[] FluxScratch; // mutable per-tick scratch for Q_kW pre-pass
13+
14+
internal readonly double CoolerInputKW; // (0 if no cooler installed)
15+
internal readonly double CoolerFrac; // fraction-of-Carnot at CoolerLowestTempK
16+
internal readonly double CoolerLowestTempK; // cold-side T of the cooler
917

10-
internal BgBoiloffCache(string dataVersion, int mliLayers, BgTankEntry[] tanks)
18+
internal BgBoiloffCache(int mliLayers, BgTankEntry[] tanks,
19+
double coolerInputKW, double coolerFrac, double coolerLowestTempK)
1120
{
12-
DataVersion = dataVersion;
1321
MliLayers = mliLayers;
1422
Tanks = tanks;
1523
InternalTemps = new double[tanks.Length];
16-
for (int i = 0; i < tanks.Length; i++) InternalTemps[i] = -1d;
24+
FluxScratch = new double[tanks.Length];
25+
CoolerInputKW = coolerInputKW;
26+
CoolerFrac = coolerFrac;
27+
CoolerLowestTempK = coolerLowestTempK;
28+
}
29+
30+
internal static BgBoiloffCache Build(string data, string coolerData, int mliLayers)
31+
{
32+
var tanks = new List<BgTankEntry>();
33+
34+
foreach (string entry in data.Split(';'))
35+
{
36+
if (string.IsNullOrEmpty(entry)) continue;
37+
string[] split = entry.Split(',');
38+
if (split.Length != 7) continue;
39+
40+
string resourceName = split[0];
41+
if (!double.TryParse(split[1], NumberStyles.Float, CultureInfo.InvariantCulture, out double boilingPointK)) continue;
42+
if (!double.TryParse(split[2], NumberStyles.Float, CultureInfo.InvariantCulture, out double tankAreaM2)) continue;
43+
if (!double.TryParse(split[3], NumberStyles.Float, CultureInfo.InvariantCulture, out double conductWPerK)) continue;
44+
if (!int.TryParse(split[4], out int isDewarInt)) continue;
45+
if (!double.TryParse(split[5], NumberStyles.Float, CultureInfo.InvariantCulture, out double hsp)) continue;
46+
if (!double.TryParse(split[6], NumberStyles.Float, CultureInfo.InvariantCulture, out double structThermalMassKJ)) continue;
47+
48+
PartResourceDefinition resDef = PartResourceLibrary.Instance.GetDefinition(resourceName);
49+
if (resDef == null || resDef.density <= 0d) continue;
50+
if (!MFSSettings.resourceVsps.TryGetValue(resourceName, out double vsp) || vsp <= 0) continue;
51+
52+
tanks.Add(new BgTankEntry
53+
{
54+
Name = resourceName,
55+
Vsp = vsp,
56+
Density = resDef.density,
57+
BoilingPointK = boilingPointK,
58+
TankAreaM2 = tankAreaM2,
59+
ConductWPerK = conductWPerK,
60+
IsDewar = isDewarInt != 0,
61+
Hsp = hsp,
62+
StructThermalMassKJ = structThermalMassKJ,
63+
});
64+
}
65+
66+
double coolerInputKW = 0d, coolerFrac = 0d, coolerLowestTempK = 0d;
67+
if (!string.IsNullOrEmpty(coolerData))
68+
{
69+
string[] cSplit = coolerData.Split(',');
70+
if (cSplit.Length == 3
71+
&& double.TryParse(cSplit[0], NumberStyles.Float, CultureInfo.InvariantCulture, out coolerInputKW)
72+
&& double.TryParse(cSplit[1], NumberStyles.Float, CultureInfo.InvariantCulture, out coolerFrac)
73+
&& double.TryParse(cSplit[2], NumberStyles.Float, CultureInfo.InvariantCulture, out coolerLowestTempK))
74+
{
75+
// ok
76+
}
77+
else
78+
{
79+
coolerInputKW = 0d; coolerFrac = 0d; coolerLowestTempK = 0d;
80+
}
81+
}
82+
83+
return new BgBoiloffCache(mliLayers, tanks.ToArray(), coolerInputKW, coolerFrac, coolerLowestTempK);
84+
}
85+
86+
internal void InitTemps(ProtoPartModuleSnapshot proto_module)
87+
{
88+
// Seed InternalTemps from the persisted TANK nodes
89+
var tempLookup = new Dictionary<string, double>(StringComparer.Ordinal);
90+
foreach (ConfigNode tankNode in proto_module.moduleValues.GetNodes("TANK"))
91+
{
92+
string tName = tankNode.GetValue("name");
93+
string sVal = tankNode.GetValue("internalTemp");
94+
if (tName != null && double.TryParse(sVal, NumberStyles.Float, CultureInfo.InvariantCulture, out double t))
95+
tempLookup[tName] = t;
96+
}
97+
98+
for (int i = 0; i < Tanks.Length; i++)
99+
{
100+
InternalTemps[i] = tempLookup.TryGetValue(Tanks[i].Name, out double v) && v > 0
101+
? v : Tanks[i].BoilingPointK;
102+
}
17103
}
18104
}
19105

Source/Tanks/MFSSettings.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ public class MFSSettings
1414
public static bool partUtilizationTweakable = false;
1515
public static string unitLabel = "u";
1616
public static bool basemassUseTotalVolume = false;
17-
public static double radiatorMinTempMult = 0.99d;
1817

1918
// Move all possible tank upgrades into the preview list in OnStart
2019
// It requires an external mod to be responsible for calling the Validate() method.
@@ -99,7 +98,6 @@ public static void ModuleManagerPostLoad()
9998
node.TryGetValue("partUtilizationTweakable", ref partUtilizationTweakable);
10099
node.TryGetValue("unitLabel", ref unitLabel);
101100
node.TryGetValue("basemassUseTotalVolume", ref basemassUseTotalVolume);
102-
node.TryGetValue("radiatorMinTempMult", ref radiatorMinTempMult);
103101
node.TryGetValue("previewAllLockedTypes", ref previewAllLockedTypes);
104102

105103
ignoreFuelsForFill.Clear();

0 commit comments

Comments
 (0)