/// <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> /// 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> /// Main method which performs a calculation /// </summary> /// <param name="calculationType">Name of the calculation method</param> /// <param name="results">Containier where result variables are supposed to be saved</param> /// <param name="variablesAtAllStep">Container of variables at each calculation step</param> /// <param name="async">Flag which specifies if it is calculated in parallel mode</param> /// <returns>Calculation time</returns> public double Calculate(CalculationTypeName calculationType, out List <DEVariable> results, List <List <DEVariable> > variablesAtAllStep = null) { // Checking the correctness of input variables DifferentialEquationSystemHelpers.CheckVariables(this.ExpressionSystem, this.LeftVariables, this.TimeVariable, this.Tau, this.TEnd); Func <List <List <DEVariable> >, List <DEVariable> > F = this.DefineSuitableMethod(calculationType); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); results = F(variablesAtAllStep); stopwatch.Stop(); return(stopwatch.ElapsedMilliseconds / 1000.0); }
private async Task <ConcurrentDictionary <CalculationTypeName, double> > CalculateForMethodGroupAsync(List <CalculationTypeName> calculationTypes, ConcurrentDictionary <CalculationTypeName, List <DEVariable> > results, ConcurrentDictionary <CalculationTypeName, List <List <DEVariable> > > variablesAtAllSteps = null, bool async = false) { ConcurrentDictionary <CalculationTypeName, double> timeResults = new ConcurrentDictionary <CalculationTypeName, double>(); // Checking the correctness of input variables DifferentialEquationSystemHelpers.CheckVariables(this.ExpressionSystem, this.LeftVariables, this.TimeVariable, this.Tau, this.TEnd); List <Task> calculationTasks = new List <Task>(); foreach (CalculationTypeName calculationType in calculationTypes) { Func <List <List <DEVariable> >, List <DEVariable> > F = this.DefineSuitableMethod(calculationType); Task calculationTask = new Task(() => { Stopwatch stopwatch = new Stopwatch(); List <DEVariable> localResult; List <List <DEVariable> > variablesAtAllStepsForMethod = new List <List <DEVariable> >(); stopwatch.Start(); localResult = F(variablesAtAllStepsForMethod); stopwatch.Stop(); results.TryAdd(calculationType, localResult); timeResults.TryAdd(calculationType, stopwatch.ElapsedMilliseconds / 1000.0); if (variablesAtAllSteps != null) { variablesAtAllSteps.TryAdd(calculationType, variablesAtAllStepsForMethod); } }); calculationTask.Start(); calculationTasks.Add(calculationTask); } await Task.WhenAll(calculationTasks); return(timeResults); }
/// <summary> /// Method which calculates a differential equation system with several specified methods. /// </summary> /// <param name="calculationTypes">List of calculation types which the system is supposed to be calculated with</param> /// <param name="results">Container where results will be saved</param> /// <param name="variablesAtAllSteps">Container of variables at each calculation step for all methods</param> /// <param name="async">Flag which specifies if it is calculated in parallel mode</param> /// <returns>Containier with calculation time</returns> public Dictionary <CalculationTypeName, double> CalculateWithGroupOfMethodsSync(List <CalculationTypeName> calculationTypes, out Dictionary <CalculationTypeName, List <DEVariable> > results, Dictionary <CalculationTypeName, List <List <DEVariable> > > variablesAtAllSteps = null) { results = new Dictionary <CalculationTypeName, List <DEVariable> >(); Dictionary <CalculationTypeName, double> timeResults = new Dictionary <CalculationTypeName, double>(); // Checking the correctness of input variables DifferentialEquationSystemHelpers.CheckVariables(this.ExpressionSystem, this.LeftVariables, this.TimeVariable, this.Tau, this.TEnd); List <List <DEVariable> > variablesForEachMethod = null; if (variablesAtAllSteps != null) { variablesForEachMethod = new List <List <DEVariable> >(); } foreach (CalculationTypeName calculationType in calculationTypes) { Func <List <List <DEVariable> >, List <DEVariable> > F = this.DefineSuitableMethod(calculationType); List <DEVariable> methodResults; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); methodResults = F(variablesForEachMethod); stopwatch.Stop(); results.Add(calculationType, methodResults); timeResults.Add(calculationType, stopwatch.ElapsedMilliseconds / 1000.0); if (variablesAtAllSteps != null) { variablesAtAllSteps.Add(calculationType, variablesForEachMethod); } } return(timeResults); }
/// <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 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 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); }