/// <summary> /// Sets the initial parameters of the DifferentialEquationSystem class. /// </summary> /// <param name="expressions">List of expressions</param> /// <param name="leftVariables">List of left variables</param> /// <param name="constants">List of constants</param> /// <param name="timeVariable">Start time (presents in the expressions)</param> /// <param name="tEnd">End time</param> /// <param name="tau">Calculation step</param> public DifferentialEquationSystem(List <string> expressions, List <DEVariable> leftVariables, List <DEVariable> constants, DEVariable timeVariable, double tEnd, double tau) { // Setting up of variables and constants if (leftVariables != null) { this.LeftVariables = DifferentialEquationSystemHelpers.ConvertDEVariablesToVariables(leftVariables); } if (constants != null) { this.Constants = DifferentialEquationSystemHelpers.ConvertDEVariablesToVariables(constants); } if (timeVariable != null) { this.TimeVariable = timeVariable; } // Setting up of all variables List <Variable> allVariables = new List <Variable>(); if (this.LeftVariables != null) { allVariables.AddRange(this.LeftVariables); } if (this.Constants != null && this.Constants.Count > 0) { allVariables.AddRange(this.Constants); } if (this.TimeVariable != null) { allVariables.Add(this.TimeVariable); } // Setting up of all expressions if (expressions == null || expressions.Count == 0) { throw new ArgumentException("Container 'expressions' of the constructor cannot be null or empty! Nothing in the differential equation system."); } else { this.Expressions = expressions; List <Expression> expressionSystem = new List <Expression>(); foreach (string expression in expressions) { expressionSystem.Add(new Expression(expression, allVariables)); } this.ExpressionSystem = expressionSystem; } this.TEnd = tEnd; this.Tau = tau; DifferentialEquationSystemHelpers.CheckVariables(this.ExpressionSystem, this.LeftVariables, this.TimeVariable, this.Tau, this.TEnd); }
/// <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); }