/// <summary> /// Updates the time history of the entire cluster (if <see cref="adaptive"/>== false), or /// of each cell (if <see cref="adaptive"/>== true) /// </summary> /// <param name="dt"></param> protected virtual void UpdateTimeHistory(double dt) { using (new ilPSP.Tracing.FuncTrace("UpdateTimeHistory")) { if (adaptive) { double[] currentTime = new double[ABSubGrid.LocalNoOfCells]; for (int i = 0; i < currentTime.Length; i++) { currentTime[i] = m_Time; } historyTimePerCell.Enqueue(currentTime); if (historyTimePerCell.Count > order - 1) //eventuell nicht nötig, später mal überprüfen { historyTimePerCell.Dequeue(); } } else { HistoryTime.Enqueue(m_Time + dt); // --> später noch schön machen und ähnlich wie timeHistoryPerCell, einen eintrag weglassen, weil das eh m_time ist! if (HistoryTime.Count >= order) //eventuell nicht nötig, später mal überprüfen { HistoryTime.Dequeue(); } } } }
/// <summary> /// performs one time step /// </summary> /// <param name="dt">size of time step</param> public override double Perform(double dt) { using (new ilPSP.Tracing.FuncTrace()) { if (TimeStepConstraints != null) { dt = CalculateTimeStep(); } // new array object needed, because currentChangeRate from last time steps are stored in historyCR queue (in queues are only references of the array) CurrentChangeRate = new double[Mapping.LocalLength]; CompleteChangeRate = new double[Mapping.LocalLength]; // AB only possible if history with "order-1" entries exists // e.g: order=3 needs t_n (currentChangeRate), t_n-1 (history(2)), t_n-2 (history(1)) --> history has 2 entries if (HistoryChangeRate.Count >= order - 1) { ABCoefficients = ComputeCoefficients(dt, HistoryTime.ToArray()); ComputeChangeRate(CurrentChangeRate, m_Time, 0); //y <-- alpha*x + y BLAS.daxpy(CompleteChangeRate.Length, ABCoefficients[0], CurrentChangeRate, 1, CompleteChangeRate, 1); // calculate completeChangeRate int i = 1; foreach (double[] oldRate in HistoryChangeRate) { BLAS.daxpy(CompleteChangeRate.Length, ABCoefficients[i], oldRate, 1, CompleteChangeRate, 1); i++; } // perform time step CurrentState.axpy <double[]>(CompleteChangeRate, -1); m_Time += dt; HistoryTime.Enqueue(m_Time); HistoryTime.Dequeue(); HistoryChangeRate.Enqueue(CurrentChangeRate); HistoryChangeRate.Dequeue(); } else { if (HistoryTime.Count == 0) { HistoryTime.Enqueue(RungeKuttaScheme.Time); } // Needed for the history ComputeChangeRate(CurrentChangeRate, m_Time, 0); // RungeKutta with order+1 starts the time stepping RungeKuttaScheme.Perform(dt); // Disposal RK after "order" of time steps if (HistoryChangeRate.Count == order - 1) { RungeKuttaScheme = null; } m_Time = RungeKuttaScheme.Time; HistoryTime.Enqueue(RungeKuttaScheme.Time); HistoryChangeRate.Enqueue(CurrentChangeRate); } } return(dt); }