Open gotmachine opened 3 years ago
Like irradiances, radiation evaluation is also subject to huge inaccuracies at high timewarp rates. Ideally, we should move it to the substep simulation. Said plainly, that whole portion of code : https://github.com/Kerbalism/Kerbalism4/blob/1e390eb8ef80632d9a641641f07a571ad1492a49/src/Kerbalism/Database/VesselData/VesselData.cs#L979-L1002 In terms of final output, this translate into getting substepped averages (instead of "current position") for the following VesselData radiation rates (rad/s):
/// <summary> ambiant radiation from the inner belt</summary>
public virtual double EnvRadiationInnerBelt { get; }
/// <summary> ambiant radiation from the outer belt</summary>
public virtual double EnvRadiationOuterBelt { get; }
/// <summary> ambiant radiation from the magnetopause</summary>
public virtual double EnvRadiationMagnetopause { get; }
/// <summary> directional radiation from the surface</summary>
public virtual double EnvRadiationBodies { get; }
/// <summary> directional radiation from the sun(s)</summary>
public virtual double EnvRadiationSolar { get; }
/// <summary> directional radiation from solar storm</summary>
public virtual double EnvStormRadiation { get; }
/// <summary> proportion of ionizing radiation not blocked by atmosphere</summary>
public virtual double EnvGammaTransparency { get; }
The current code is a bit messy. The core method to port is the Radiation.Compute()
method (which is currently a bit messy and was pending a refactor/cleanup) :
https://github.com/Kerbalism/Kerbalism4/blob/1e390eb8ef80632d9a641641f07a571ad1492a49/src/Kerbalism/Radiation/Radiation.cs#L618-L770
You will notice that for each of the above variable, there is a matching boolean. This is because we used to only output the "total" aggregate radiation, and booleans to identify what sources were "active". I quick-and-dirty changed that recently so we have access to the detail rate of each source, but I was also in the process of refactoring the whole thing so EnvRadiationSolar
is tracked per sun, and EnvRadiationBodies
per body (because they are directional, and I was planning to take that into account, at least for solar radiation). Said otherwise, I intended to move EnvRadiationSolar
to the StarFlux
structure. But since you already are in the process of extending/refactoring StarFlux
to a BodyFlux
structure (and processing all bodies internally), we should likely do both from the ground up.
In terms of re-implementation, a quick overview :
You will need to make a "job-safe" copy of the RadiationBody
and RadiationModel
data structures. All values in those classes are constants, so you only need to make that once. RadiationModel
are essentially "templates", so I suggest you aggregate the data in a single "per body" data structure (and in fact, you should use the same data structure for info about stars too, instead of re-getting it every iteration. This is also constant data.)
Belts and magnetopause radiation are computed by evaluating the vessel position against the fields shape, which are represented by math functions. The called methods are a bit all over the place for no reason other than technical debt, but you should be able to rebuild the execution path quite easily by following the execution of Radiation.Compute()
(it's entirely self contained, to my knowledge there is nothing modifying the data that this depends on).
Solar/bodies radiation are directional, and affected by other bodies occlusion (and also, they are the same value in RadiationModel). From a physics POV, they are identical to the solar irradiance, so you can likely just merge that into your existing code.
Storm radiation is a bit trickier. As mentioned in #5, I intended to more or less entirely scrap the current per-vessel-random implementation, possibly in favor of generating "cone" storms, where every vessel/body inside the cone is subject to the storm. For now, I would suggest to postpone including storm radiation in the substep sim until this is done.
beloved modders, i just found out about kerbalism 4. are you still working on it? Cheers!
Replace the managed thread based substepping sim with a Jobs/Burst implementation.
Overview of the substep sim :
In
SubStepSim.OnFixedUpdate()
(called byKerbalism.FixedUpdate()
before anything else has been done) :maxFutureUT
, the maximum time in the future that might be attained in the next fixedupdate at max timewarp :currentUT + (TimeWarp.fetch.warpRates[7] * 0.02) + one extra substep just in case
maxFutureUT
Later in
Kerbalism.FixedUpdate()
,VesselData.EnvironmentUpdate
will be called. TheelapsedSeconds
parameter is checked against the substep duration "constant" (60s for example).If
elapsedSecond < substepDuration * 2.0
:SubStepSim.OnFixedUpdate()
SubStepSim.OnFixedUpdate()
)else
SubStepSim.OnFixedUpdate()
Data : current implementation performance
Save : 20 vessels.zip
Profiler results (2C/4T@4.5Ghz, Cinebench R20 MT : 1135 / ST : 453) :
Relevant metrics :