/// <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 a sub-step /// </summary> /// <param name="dt">size of time step</param> public override double Perform(double dt) { using (var tr = new ilPSP.Tracing.FuncTrace()) { // Checking History if (HistoryDGCoordinate.Count >= order) { HistoryDGCoordinate.Dequeue(); } if (HistoryChangeRate.Count >= order) { HistoryChangeRate.Dequeue(); HistoryBoundaryFluxes.Dequeue(); } // Compute AB Coefficents if (adaptive) { if (historyTimePerCell.Count > order - 1) { historyTimePerCell.Dequeue(); } ABCoefficientsPerCell = new double[ABSubGrid.LocalNoOfCells][]; for (int cell = 0; cell < ABSubGrid.LocalNoOfCells; cell++) { double[] historyTimeArray = new double[order]; int i = 0; foreach (double[] historyPerCell in historyTimePerCell) { historyTimeArray[i] = historyPerCell[cell]; i++; } historyTimeArray[i] = m_Time; ABCoefficientsPerCell[cell] = ComputeCoefficients(dt, historyTimeArray); } } else { double[] historyTimeArray = HistoryTime.ToArray(); ABCoefficients = ComputeCoefficients(dt, historyTimeArray); } double[] upDGC; CurrentChangeRate = new double[Mapping.LocalLength]; currentBndFluxes = new double[numOfEdges * Mapping.Fields.Count]; ComputeChangeRate(CurrentChangeRate, m_Time, 0, currentBndFluxes); ////////////// Calculate complete change rate with older steps MakeABStep(); // Update DGCoordinates for History // (Hint: calls extra function to gives the ability to modify the update procedure, i.e in IBM case) upDGC = ComputesUpdatedDGCoordinates(CompleteChangeRate); // Keeps track of histories HistoryDGCoordinate.Enqueue(upDGC); HistoryChangeRate.Enqueue(CurrentChangeRate); HistoryBoundaryFluxes.Enqueue(currentBndFluxes); UpdateTimeHistory(dt); // Update local sub-grid time m_Time = m_Time + dt; } return(dt); }
/// <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); }