/// <summary> /// Sync Euler calculation body /// </summary> /// <param name="variablesAtAllStep">Container where the intermediate parameters are supposed to be saved</param> /// <returns>List of result variables</returns> private List <DEVariable> EulerSync(List <List <DEVariable> > variablesAtAllStep = null) { // Put left variables, constants and time variable in the one containier List <Variable> allVars; List <Variable> currentLeftVariables = new List <Variable>(); List <Variable> nextLeftVariables = new List <Variable>(); // Copy this.LeftVariables to the current one and to the nex one // To leave this.LeftVariables member unchanged (for further calculations) DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, currentLeftVariables); DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, nextLeftVariables); // Setting of current time (to leave this.TimeVariable unchanged) Variable currentTime = new Variable(this.TimeVariable); // If it is required to save intermediate calculations - save the start values if (variablesAtAllStep != null) { // This is the first record for intermediate calculations containier // It has to be clear variablesAtAllStep.Clear(); DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, this.LeftVariables, currentTime); } do { // Combinig of variables allVars = DifferentialEquationSystemHelpers.CollectVariables(currentLeftVariables, this.Constants, currentTime); // Calculation for (int i = 0; i < nextLeftVariables.Count; i++) { nextLeftVariables[i].Value = currentLeftVariables[i].Value + this.Tau * this.ExpressionSystem[i].GetResultValue(allVars); } // Saving of all variables at current iteration if (variablesAtAllStep != null) { DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, nextLeftVariables, currentTime); } // Next variables are becoming the current ones for the next iteration DifferentialEquationSystemHelpers.CopyVariables(nextLeftVariables, currentLeftVariables); // calculation time incrimentation currentTime.Value += this.Tau; } while (currentTime.Value < this.TEnd); List <DEVariable> result = new List <DEVariable>(); DifferentialEquationSystemHelpers.CopyVariables(currentLeftVariables, result); return(result); }
/// <summary> /// Method calculates a differential equation system with RK4 method /// </summary> /// <param name="variablesAtAllStep">Container where the intermediate parameters are supposed to be saved</param> /// <returns>List of result variables</returns> private List <DEVariable> RK4Async(List <List <DEVariable> > variablesAtAllStep) { // Put left variables, constants and time variable in the one containier List <Variable> allVars; List <Variable> currentLeftVariables = new List <Variable>(); List <Variable> leftVariablesK1 = new List <Variable>(); List <Variable> leftVariablesK2 = new List <Variable>(); List <Variable> leftVariablesK3 = new List <Variable>(); List <Variable> nextLeftVariables = new List <Variable>(); // Copy this.LeftVariables to the current one and to the nex one // To leave this.LeftVariables member unchanged (for further calculations) DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, currentLeftVariables); DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, leftVariablesK1); DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, leftVariablesK2); DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, leftVariablesK3); DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, nextLeftVariables); // Setting of current time (to leave this.TimeVariable unchanged) Variable currentTime = new Variable(this.TimeVariable); if (variablesAtAllStep != null) { // This is the first record for intermediate calculations containier // It has to be clear variablesAtAllStep.Clear(); // Copying of the initial left variables to the separate list which when is going to "variablesAtAllStep" containier DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, this.LeftVariables, currentTime); } do { // Preparation of variables for K1 calculation allVars = DifferentialEquationSystemHelpers.CollectVariables(currentLeftVariables, this.Constants, currentTime); // K1 calculation double[] K1 = new double[currentLeftVariables.Count]; Parallel.For(0, K1.Length, (i) => { K1[i] = this.ExpressionSystem[i].GetResultValue(allVars); }); // Preparation of variables for K2 calculation Parallel.For(0, currentLeftVariables.Count, (i) => { leftVariablesK1[i].Value = currentLeftVariables[i].Value + this.Tau / 2 * K1[i]; }); allVars = DifferentialEquationSystemHelpers.CollectVariables(leftVariablesK1, this.Constants, new Variable(currentTime.Name, currentTime.Value + this.Tau / 2)); // K2 calculation double[] K2 = new double[currentLeftVariables.Count]; Parallel.For(0, K2.Length, (i) => { K2[i] = this.ExpressionSystem[i].GetResultValue(allVars); }); Parallel.For(0, currentLeftVariables.Count, (i) => { leftVariablesK2[i].Value = currentLeftVariables[i].Value + this.Tau / 2 * K2[i]; }); allVars = DifferentialEquationSystemHelpers.CollectVariables(leftVariablesK2, this.Constants, new Variable(currentTime.Name, currentTime.Value + this.Tau / 2)); // K3 calculation double[] K3 = new double[currentLeftVariables.Count]; Parallel.For(0, K3.Length, (i) => { K3[i] = this.ExpressionSystem[i].GetResultValue(allVars); }); Parallel.For(0, currentLeftVariables.Count, (i) => { leftVariablesK3[i].Value = currentLeftVariables[i].Value + this.Tau * K3[i]; }); allVars = DifferentialEquationSystemHelpers.CollectVariables(leftVariablesK3, this.Constants, new Variable(currentTime.Name, currentTime.Value + this.Tau)); // K4 calculation double[] K4 = new double[currentLeftVariables.Count]; Parallel.For(0, K4.Length, (i) => { K4[i] = this.ExpressionSystem[i].GetResultValue(allVars); }); Parallel.For(0, currentLeftVariables.Count, (i) => { nextLeftVariables[i].Value = currentLeftVariables[i].Value + this.Tau / 6 * (K1[i] + 2 * K2[i] + 2 * K3[i] + K4[i]); }); // Saving of all variables at current iteration if (variablesAtAllStep != null) { DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, nextLeftVariables, new Variable(currentTime.Name, currentTime.Value + this.Tau)); } // Next variables are becoming the current ones for the next iteration DifferentialEquationSystemHelpers.CopyVariables(nextLeftVariables, currentLeftVariables); currentTime.Value += this.Tau; } while (currentTime.Value < this.TEnd); List <DEVariable> result = new List <DEVariable>(); DifferentialEquationSystemHelpers.CopyVariables(currentLeftVariables, result); return(result); }
/// <summary> /// Method calculates a differential equation system with RK2 method /// </summary> /// <param name="variablesAtAllStep">Container where the intermediate parameters are supposed to be saved</param> /// <returns>List of result variables</returns> private List <DEVariable> RK2Async(List <List <DEVariable> > variablesAtAllStep) { // Put left variables, constants and time variable in the one containier List <Variable> allVars; List <Variable> currentLeftVariables = new List <Variable>(); List <Variable> halfStepVariables = new List <Variable>(); List <Variable> nextLeftVariables = new List <Variable>(); // Copy this.LeftVariables to the current one and to the nex one // To leave this.LeftVariables member unchanged (for further calculations) DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, currentLeftVariables); DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, halfStepVariables); DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, nextLeftVariables); // Setting of current time (to leave this.TimeVariable unchanged) Variable currentTime = new Variable(this.TimeVariable); if (variablesAtAllStep != null) { // This is the first record for intermediate calculations containier // It has to be clear variablesAtAllStep.Clear(); // Copying of the initial left variables to the separate list which when is going to "variablesAtAllStep" containier DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, this.LeftVariables, currentTime); } do { allVars = DifferentialEquationSystemHelpers.CollectVariables(currentLeftVariables, this.Constants, currentTime); Parallel.For(0, halfStepVariables.Count, (i) => { halfStepVariables[i].Value = currentLeftVariables[i].Value + this.Tau / 2 * this.ExpressionSystem[i].GetResultValue(allVars); }); allVars = DifferentialEquationSystemHelpers.CollectVariables(halfStepVariables, this.Constants, new Variable(currentTime.Name, currentTime.Value + this.Tau / 2)); double[] halfValues = new double[currentLeftVariables.Count]; Parallel.For(0, currentLeftVariables.Count, (i) => { halfValues[i] = this.ExpressionSystem[i].GetResultValue(allVars); }); Parallel.For(0, currentLeftVariables.Count, (i) => { nextLeftVariables[i].Value = currentLeftVariables[i].Value + this.Tau * halfValues[i]; }); // Saving of all variables at current iteration if (variablesAtAllStep != null) { DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, nextLeftVariables, new Variable(currentTime.Name, currentTime.Value + this.Tau)); } // Next variables are becoming the current ones for the next iteration DifferentialEquationSystemHelpers.CopyVariables(nextLeftVariables, currentLeftVariables); // calculation time incrimentation currentTime.Value += this.Tau; } while (currentTime.Value < this.TEnd); List <DEVariable> result = new List <DEVariable>(); DifferentialEquationSystemHelpers.CopyVariables(currentLeftVariables, result); return(result); }
/// <summary> /// Method calculates a differential equation system with Extrapolation Adams One method /// </summary> /// <param name="variablesAtAllStep">Container where the intermediate parameters are supposed to be saved</param> /// <returns>List of result variables</returns> private List <DEVariable> AdamsExtrapolationOneSync(List <List <DEVariable> > variablesAtAllStep = null) { #region Calculation preparation List <Variable> allVars; List <Variable> currentLeftVariables = new List <Variable>(); List <Variable> nextLeftVariables = new List <Variable>(); // Copy this.LeftVariables to the current one and to the nex one // To leave this.LeftVariables member unchanged (for further calculations) DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, currentLeftVariables); DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, nextLeftVariables); // Setting of current time (to leave this.TimeVariable unchanged) Variable currentTime = new Variable(this.TimeVariable); // If it is required to save intermediate calculations - save the start values if (variablesAtAllStep != null) { // This is the first record for intermediate calculations containier // It has to be clear variablesAtAllStep.Clear(); DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, this.LeftVariables, currentTime); } #endregion #region First variables // Varables at "timestart + tau" is supposed to be calculated with other method // It was chosen to use Euler method // Generated a new instance for its calculation DifferentialEquationSystem differentialEquationSystem = new DifferentialEquationSystem(this.ExpressionSystem, this.LeftVariables, this.Constants, this.TimeVariable, this.TimeVariable.Value + this.Tau, this.Tau); // Calculation List <Variable> firstLeftVariables; differentialEquationSystem.Calculate(CalculationTypeName.Euler, out List <DEVariable> bufer); firstLeftVariables = DifferentialEquationSystemHelpers.ConvertDEVariablesToVariables(bufer); // Save the second variables calculated with Euler method if (variablesAtAllStep != null) { DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, firstLeftVariables, new Variable(currentTime.Name, currentTime.Value + this.Tau)); } #endregion allVars = DifferentialEquationSystemHelpers.CollectVariables(currentLeftVariables, this.Constants, currentTime); double[,] Q = new double[2, this.ExpressionSystem.Count]; for (int i = 0; i < this.ExpressionSystem.Count; i++) { Q[0, i] = this.Tau * this.ExpressionSystem[i].GetResultValue(allVars); } currentTime.Value += this.Tau; allVars = DifferentialEquationSystemHelpers.CollectVariables(firstLeftVariables, this.Constants, currentTime); for (int i = 0; i < this.ExpressionSystem.Count; i++) { Q[1, i] = this.Tau * this.ExpressionSystem[i].GetResultValue(allVars); } do { for (int i = 0; i < nextLeftVariables.Count; i++) { nextLeftVariables[i].Value = currentLeftVariables[i].Value + 0.5 * (3 * Q[1, i] - Q[0, i]); } allVars = DifferentialEquationSystemHelpers.CollectVariables(nextLeftVariables, this.Constants, new Variable(currentTime.Name, currentTime.Value + this.Tau)); for (int i = 0; i < nextLeftVariables.Count; i++) { Q[0, i] = Q[1, i]; Q[1, i] = this.Tau * this.ExpressionSystem[i].GetResultValue(allVars); } if (variablesAtAllStep != null) { DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, nextLeftVariables, new Variable(currentTime.Name, currentTime.Value + this.Tau)); } DifferentialEquationSystemHelpers.CopyVariables(nextLeftVariables, currentLeftVariables); // calculation time incrimentation currentTime.Value += this.Tau; } while (currentTime.Value < this.TEnd); List <DEVariable> result = new List <DEVariable>(); DifferentialEquationSystemHelpers.CopyVariables(currentLeftVariables, result); return(result); }
/// <summary> /// Method calculates a differential equation system with Extrapolation Adams Three method /// </summary> /// <param name="variablesAtAllStep">Container where the intermediate parameters are supposed to be saved</param> /// <returns>List of result variables</returns> private List <DEVariable> AdamsExtrapolationThreeAsync(List <List <DEVariable> > variablesAtAllStep = null) { #region Calculation preparation List <Variable> allVars; List <Variable> currentLeftVariables = new List <Variable>(); List <Variable> nextLeftVariables = new List <Variable>(); // Copy this.LeftVariables to the current one and to the nex one // To leave this.LeftVariables member unchanged (for further calculations) DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, currentLeftVariables); DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, nextLeftVariables); // Setting of current time (to leave this.TimeVariable unchanged) Variable currentTime = new Variable(this.TimeVariable); // If it is required to save intermediate calculations - save the start values if (variablesAtAllStep != null) { // This is the first record for intermediate calculations containier // It has to be clear variablesAtAllStep.Clear(); DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, this.LeftVariables, currentTime); } #endregion #region First variables DifferentialEquationSystem differentialEquationSystem = new DifferentialEquationSystem(this.ExpressionSystem, this.LeftVariables, this.Constants, this.TimeVariable, this.TimeVariable.Value + 3 * this.Tau, this.Tau); List <List <DEVariable> > firstVariables = new List <List <DEVariable> >(); differentialEquationSystem.Calculate(CalculationTypeName.Euler, out List <DEVariable> bufer, firstVariables); List <Variable> firstLeftVariables; List <Variable> secondLeftVariables; List <Variable> thirdLeftVariables; firstLeftVariables = DifferentialEquationSystemHelpers.ConvertDEVariablesToVariables(firstVariables[1]); secondLeftVariables = DifferentialEquationSystemHelpers.ConvertDEVariablesToVariables(firstVariables[2]); thirdLeftVariables = DifferentialEquationSystemHelpers.ConvertDEVariablesToVariables(firstVariables[3]); firstLeftVariables.RemoveAt(firstLeftVariables.Count - 1); secondLeftVariables.RemoveAt(secondLeftVariables.Count - 1); thirdLeftVariables.RemoveAt(thirdLeftVariables.Count - 1); if (variablesAtAllStep != null) { DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, firstLeftVariables, new Variable(currentTime.Name, currentTime.Value + this.Tau)); DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, secondLeftVariables, new Variable(currentTime.Name, currentTime.Value + 2 * this.Tau)); DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, thirdLeftVariables, new Variable(currentTime.Name, currentTime.Value + 3 * this.Tau)); } #endregion double[,] Q = new double[4, this.ExpressionSystem.Count]; allVars = DifferentialEquationSystemHelpers.CollectVariables(currentLeftVariables, this.Constants, currentTime); Parallel.For(0, this.ExpressionSystem.Count, (i) => { Q[0, i] = this.Tau * this.ExpressionSystem[i].GetResultValue(allVars); }); currentTime.Value += this.Tau; allVars = DifferentialEquationSystemHelpers.CollectVariables(firstLeftVariables, this.Constants, currentTime); Parallel.For(0, this.ExpressionSystem.Count, (i) => { Q[1, i] = this.Tau * this.ExpressionSystem[i].GetResultValue(allVars); }); currentTime.Value += this.Tau; allVars = DifferentialEquationSystemHelpers.CollectVariables(secondLeftVariables, this.Constants, currentTime); Parallel.For(0, this.ExpressionSystem.Count, (i) => { Q[2, i] = this.Tau * this.ExpressionSystem[i].GetResultValue(allVars); }); currentTime.Value += this.Tau; allVars = DifferentialEquationSystemHelpers.CollectVariables(thirdLeftVariables, this.Constants, currentTime); Parallel.For(0, this.ExpressionSystem.Count, (i) => { Q[3, i] = this.Tau * this.ExpressionSystem[i].GetResultValue(allVars); }); DifferentialEquationSystemHelpers.CopyVariables(thirdLeftVariables, currentLeftVariables); do { Parallel.For(0, nextLeftVariables.Count, (i) => { nextLeftVariables[i].Value = currentLeftVariables[i].Value + 1.0 / 24 * (55 * Q[3, i] - 59 * Q[2, i] + 37 * Q[1, i] - 9 * Q[0, i]); }); allVars = DifferentialEquationSystemHelpers.CollectVariables(nextLeftVariables, this.Constants, new Variable(currentTime.Name, currentTime.Value + this.Tau)); Parallel.For(0, nextLeftVariables.Count, (i) => { Q[0, i] = Q[1, i]; Q[1, i] = Q[2, i]; Q[2, i] = Q[3, i]; Q[3, i] = this.Tau * this.ExpressionSystem[i].GetResultValue(allVars); }); if (variablesAtAllStep != null) { DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, nextLeftVariables, new Variable(currentTime.Name, currentTime.Value + this.Tau)); } DifferentialEquationSystemHelpers.CopyVariables(nextLeftVariables, currentLeftVariables); currentTime.Value += this.Tau; } while (currentTime.Value < this.TEnd); List <DEVariable> result = new List <DEVariable>(); DifferentialEquationSystemHelpers.CopyVariables(currentLeftVariables, result); return(result); }
/// <summary> /// Method calculates a differential equation system with Miln method /// </summary> /// <param name="variablesAtAllStep">Container where the intermediate parameters are supposed to be saved</param> /// <returns>List of result variables</returns> private List <DEVariable> MilnSync(List <List <DEVariable> > variablesAtAllStep = null) { #region Calculation preparation List <Variable> allVars; List <Variable> currentLeftVariables = new List <Variable>(); List <Variable> milnPredicted = new List <Variable>(); List <Variable> nextLeftVariables = new List <Variable>(); // Copy this.LeftVariables to the current one and to the nex one // To leave this.LeftVariables member unchanged (for further calculations) DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, currentLeftVariables); DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, milnPredicted); DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, nextLeftVariables); // Setting of current time (to leave this.TimeVariable unchanged) Variable currentTime = new Variable(this.TimeVariable); // If it is required to save intermediate calculations - save the start values if (variablesAtAllStep != null) { // This is the first record for intermediate calculations containier // It has to be clear variablesAtAllStep.Clear(); DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, this.LeftVariables, currentTime); } #endregion #region First variables DifferentialEquationSystem differentialEquationSystem = new DifferentialEquationSystem(this.ExpressionSystem, this.LeftVariables, this.Constants, this.TimeVariable, this.TimeVariable.Value + 3 * this.Tau, this.Tau); List <List <DEVariable> > firstVariables = new List <List <DEVariable> >(); List <DEVariable> bufer; differentialEquationSystem.Calculate(CalculationTypeName.Euler, out bufer, firstVariables); List <Variable> firstLeftVariables; List <Variable> secondLeftVariables; List <Variable> thirdLeftVariables; firstLeftVariables = DifferentialEquationSystemHelpers.ConvertDEVariablesToVariables(firstVariables[1]); secondLeftVariables = DifferentialEquationSystemHelpers.ConvertDEVariablesToVariables(firstVariables[2]); thirdLeftVariables = DifferentialEquationSystemHelpers.ConvertDEVariablesToVariables(firstVariables[3]); firstLeftVariables.RemoveAt(firstLeftVariables.Count - 1); secondLeftVariables.RemoveAt(secondLeftVariables.Count - 1); thirdLeftVariables.RemoveAt(thirdLeftVariables.Count - 1); if (variablesAtAllStep != null) { DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, firstLeftVariables, new Variable(currentTime.Name, currentTime.Value + this.Tau)); DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, secondLeftVariables, new Variable(currentTime.Name, currentTime.Value + 2 * this.Tau)); DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, thirdLeftVariables, new Variable(currentTime.Name, currentTime.Value + 3 * this.Tau)); } #endregion double[,] Q = new double[4, this.ExpressionSystem.Count]; double[,] prevValues = new double[4, this.ExpressionSystem.Count]; allVars = DifferentialEquationSystemHelpers.CollectVariables(currentLeftVariables, this.Constants, currentTime); for (int i = 0; i < this.ExpressionSystem.Count; i++) { Q[0, i] = this.ExpressionSystem[i].GetResultValue(allVars); prevValues[0, i] = currentLeftVariables[i].Value; } currentTime.Value += this.Tau; allVars = DifferentialEquationSystemHelpers.CollectVariables(firstLeftVariables, this.Constants, currentTime); for (int i = 0; i < this.ExpressionSystem.Count; i++) { Q[1, i] = this.ExpressionSystem[i].GetResultValue(allVars); prevValues[1, i] = firstLeftVariables[i].Value; } currentTime.Value += this.Tau; allVars = DifferentialEquationSystemHelpers.CollectVariables(secondLeftVariables, this.Constants, currentTime); for (int i = 0; i < this.ExpressionSystem.Count; i++) { Q[2, i] = this.ExpressionSystem[i].GetResultValue(allVars); prevValues[2, i] = secondLeftVariables[i].Value; } currentTime.Value += this.Tau; allVars = DifferentialEquationSystemHelpers.CollectVariables(thirdLeftVariables, this.Constants, currentTime); for (int i = 0; i < this.ExpressionSystem.Count; i++) { Q[3, i] = this.ExpressionSystem[i].GetResultValue(allVars); prevValues[3, i] = thirdLeftVariables[i].Value; } DifferentialEquationSystemHelpers.CopyVariables(thirdLeftVariables, currentLeftVariables); do { for (int i = 0; i < milnPredicted.Count; i++) { milnPredicted[i].Value = prevValues[0, i] + 4 * this.Tau / 3 * (2 * Q[1, i] - Q[2, i] + 2 * Q[3, i]); } double[] predictedValues = new double[milnPredicted.Count]; allVars = DifferentialEquationSystemHelpers.CollectVariables(milnPredicted, this.Constants, new Variable(currentTime.Name, currentTime.Value + this.Tau)); for (int i = 0; i < predictedValues.Length; i++) { predictedValues[i] = this.ExpressionSystem[i].GetResultValue(allVars); } for (int i = 0; i < nextLeftVariables.Count; i++) { nextLeftVariables[i].Value = prevValues[2, i] + this.Tau / 3 * (Q[2, i] + 4 * this.ExpressionSystem[i].GetResultValue(DifferentialEquationSystemHelpers.CollectVariables(currentLeftVariables, this.Constants, currentTime)) + predictedValues[i]); } allVars = DifferentialEquationSystemHelpers.CollectVariables(nextLeftVariables, this.Constants, new Variable(currentTime.Name, currentTime.Value + this.Tau)); for (int i = 0; i < nextLeftVariables.Count; i++) { Q[0, i] = Q[1, i]; Q[1, i] = Q[2, i]; Q[2, i] = Q[3, i]; Q[3, i] = this.ExpressionSystem[i].GetResultValue(allVars); prevValues[0, i] = prevValues[1, i]; prevValues[1, i] = prevValues[2, i]; prevValues[2, i] = prevValues[3, i]; prevValues[3, i] = nextLeftVariables[i].Value; } if (variablesAtAllStep != null) { DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, nextLeftVariables, new Variable(currentTime.Name, currentTime.Value + this.Tau)); } DifferentialEquationSystemHelpers.CopyVariables(nextLeftVariables, currentLeftVariables); currentTime.Value += this.Tau; } while (currentTime.Value < this.TEnd); List <DEVariable> result = new List <DEVariable>(); DifferentialEquationSystemHelpers.CopyVariables(currentLeftVariables, result); return(result); }
/// <summary> /// Method calculates a differential equation system with Forecast-Correction method /// </summary> /// <param name="variablesAtAllStep">Container where the intermediate parameters are supposed to be saved</param> /// <returns>List of result variables</returns> private List <DEVariable> ForecastCorrectionAsync(List <List <DEVariable> > variablesAtAllStep = null) { // Put left variables, constants and time variable in the one containier List <Variable> allVars; List <Variable> currentLeftVariables = new List <Variable>(); List <Variable> predictedLeftVariables = new List <Variable>(); List <Variable> nextLeftVariables = new List <Variable>(); // Copy this.LeftVariables to the current one and to the nex one // To leave this.LeftVariables member unchanged (for further calculations) DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, currentLeftVariables); DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, predictedLeftVariables); DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, nextLeftVariables); Variable currentTime = new Variable(this.TimeVariable); if (variablesAtAllStep != null) { // This is the first record for intermediate calculations containier // It has to be clear variablesAtAllStep.Clear(); DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, this.LeftVariables, currentTime); } do { // Combinig of variables to calculate the next step results allVars = DifferentialEquationSystemHelpers.CollectVariables(currentLeftVariables, this.Constants, currentTime); // Calculation of functions values for the next steps double[] FCurrent = new double[this.ExpressionSystem.Count]; Parallel.For(0, currentLeftVariables.Count, (i) => { FCurrent[i] = this.ExpressionSystem[i].GetResultValue(allVars); }); // Calculation of variables for the next steps Parallel.For(0, predictedLeftVariables.Count, (i) => { predictedLeftVariables[i].Value = currentLeftVariables[i].Value + this.Tau * this.ExpressionSystem[i].GetResultValue(allVars); }); // Combinig of variables with ones taken from the previous iteration (variables for the next step) allVars = DifferentialEquationSystemHelpers.CollectVariables(predictedLeftVariables, this.Constants, new Variable(currentTime.Name, currentTime.Value + this.Tau)); // Calculation of the next variables double[] FPredicted = new double[this.ExpressionSystem.Count]; Parallel.For(0, predictedLeftVariables.Count, (i) => { FPredicted[i] = this.ExpressionSystem[i].GetResultValue(allVars); }); // Calculation of the next variables Parallel.For(0, predictedLeftVariables.Count, (i) => { nextLeftVariables[i].Value = currentLeftVariables[i].Value + this.Tau * (FCurrent[i] + FPredicted[i]) / 2; }); if (variablesAtAllStep != null) { DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, nextLeftVariables, new Variable(currentTime.Name, currentTime.Value + this.Tau)); } DifferentialEquationSystemHelpers.CopyVariables(nextLeftVariables, currentLeftVariables); currentTime.Value += this.Tau; } while (currentTime.Value < this.TEnd); List <DEVariable> result = new List <DEVariable>(); DifferentialEquationSystemHelpers.CopyVariables(currentLeftVariables, result); return(result); }
/// <summary> /// Method calculates a differential equation system with Forecast-Correction method /// </summary> /// <param name="variablesAtAllStep">Container where the intermediate parameters are supposed to be saved</param> /// <returns>List of result variables</returns> private List <DEVariable> ForecastCorrectionSync(List <List <DEVariable> > variablesAtAllStep = null) { // Put left variables, constants and time variable in the one containier List <Variable> allVars; List <Variable> currentLeftVariables = new List <Variable>(); List <Variable> predictedLeftVariables = new List <Variable>(); List <Variable> nextLeftVariables = new List <Variable>(); // Copy this.LeftVariables to the current one and to the nex one // To leave this.LeftVariables member unchanged (for further calculations) DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, currentLeftVariables); DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, predictedLeftVariables); DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, nextLeftVariables); // Setting of current time (to leave this.TimeVariable unchanged) Variable currentTime = new Variable(this.TimeVariable); if (variablesAtAllStep != null) { // This is the first record for intermediate calculations containier // It has to be clear variablesAtAllStep.Clear(); DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, this.LeftVariables, currentTime); } do { // Combinig of variables to calculate the next step results allVars = DifferentialEquationSystemHelpers.CollectVariables(currentLeftVariables, this.Constants, currentTime); // Calculation of functions values for the next steps List <double> FCurrent = new List <double>(); for (int i = 0; i < currentLeftVariables.Count; i++) { FCurrent.Add(this.ExpressionSystem[i].GetResultValue(allVars)); } // Calculation of variables for the next steps for (int i = 0; i < predictedLeftVariables.Count; i++) { predictedLeftVariables[i].Value = currentLeftVariables[i].Value + this.Tau * this.ExpressionSystem[i].GetResultValue(allVars); } // Combinig of variables with ones taken from the previous iteration (variables for the next step) allVars = DifferentialEquationSystemHelpers.CollectVariables(predictedLeftVariables, this.Constants, new Variable(currentTime.Name, currentTime.Value + this.Tau)); // Calculation of predicted variables List <double> FPredicted = new List <double>(); for (int i = 0; i < predictedLeftVariables.Count; i++) { FPredicted.Add(this.ExpressionSystem[i].GetResultValue(allVars)); } // Calculation of the next variables for (int i = 0; i < predictedLeftVariables.Count; i++) { nextLeftVariables[i].Value = currentLeftVariables[i].Value + this.Tau * (FCurrent[i] + FPredicted[i]) / 2; } // Saving of all variables at current iteration if (variablesAtAllStep != null) { DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, nextLeftVariables, new Variable(currentTime.Name, currentTime.Value + this.Tau)); } // Next variables are becoming the current ones for the next iteration DifferentialEquationSystemHelpers.CopyVariables(nextLeftVariables, currentLeftVariables); // calculation time incrimentation currentTime.Value += this.Tau; } while (currentTime.Value < this.TEnd); List <DEVariable> result = new List <DEVariable>(); DifferentialEquationSystemHelpers.CopyVariables(currentLeftVariables, result); return(result); }