I am experiencing some numerical misbehavior, probably because I’ve made some error writing the scripts (I am a newbie).
I wrote a code that makes a prefab “growing” following some mathematical rules. These rules are Ordinary Differential Equations solved by Runge-Kutta numerical method (https://www.codeguru.com/csharp/.net/net_general/arithmetic/article.php/c4597/Numerical-Computing-in-C.htm)
The growth script has a variable calculated as ODE solution each timestep:
public void UpdateGrowth()
{
if (timeManager.IsDayElapsed && timeManager.Seconds <= setup.SimulationTime)
{
if (internodeID <= setup.StaticGeneticInfo.MaxInternodeNumber)
setup.Manager.InternodesCurrentLenght[internodeID - 1] = transform.localScale.y;
float nextValue = nextStepValue.NextStepValue;
float dayCount = timeManager.Days;
annualLengthGrowth = Runge.runge(0.0f, 1.0f, nextValue, .1f, new Runge.Function(Equation.equation));
annualGrowth = new Vector3(annualWidthGrowth, annualLengthGrowth, annualWidthGrowth);
nextStepValue.NextStepValue = annualLengthGrowth;
currentLenght = (annualGrowth.y);
The classRunge is the one for Runge-Kutta numerical method:
public class Runge
{
//declare a delegate that takes a float and returns
public delegate float Function(float dayCount, float annualGrowth);
public static float runge(float a, float b, float value, float step, Function f)
{
float dayCount, w, k1, k2, k3, k4;
dayCount = a;
w = value;
for (int i = 0; i < (b - a) / step; i++)
{
k1 = step * f(dayCount, w);
k2 = step * f(dayCount + step / 2f, w + k1 / 2f);
k3 = step * f(dayCount + step / 2f, w + k2 / 2f);
k4 = step * f(dayCount + step, w + k3);
w = w + (k1 + 2f * k2 + 2f * k3 + k4) / 6f;
dayCount = a + i * step;
}
return w;
}
}
The equation to solve is in equation script:
public void Update()
{
dayCount = time.Days;
}
public static float equation(float dayCount, float annualGrowth)
{
float y_prime;
float maxLenght = (1 - (setup.Manager.TotalLenght() / maxTreeHeight));
temp = (float)-Math.Pow(((180 - dayCount) / 180), 2) * a + a;
alfaT = temp / a;
y_prime = alfaT * annualGrowth * (1 - (annualGrowth / maxLenght));
return y_prime;
}
While the daycount is given by timemanager script:
private void Start()
{
isdayElapsed = false;
}
private void Update()
{
rate += Time.deltaTime;
if (rate > 1)
{
rate = 0;
seconds++;
days++;
isdayElapsed = true;
}
if (days > 365)
{
days = 0;
}
}
The issue I am experiencing is that in the equation script, the dayCount variable is passed from 0 to 1, then from 1 is “resetting” calculating back from 0. This made annualLenghtGrowth in growth script miscalculated. Of course it should continue with 2, 3 ,4 and so on until 365.
It looks like is resetting each update while the dayCount is working fine.
I can’t figure out where and what is the problem, please help me.
Thank you