コード例 #1
0
ファイル: ABevolve.cs プロジェクト: octwanna/BoSSS
 /// <summary>
 /// Computes the new intermediate DGCoordinates.
 /// Important: It does not change the DGCoordinates <see cref="ExplicitEuler.DGCoordinates"/>.
 /// </summary>
 /// <param name="completeChangeRate">Complete ChangeRate of a cluster for one sub-step</param>
 /// <returns>intermediate DGCoordinates as array</returns>
 protected virtual double[] ComputesUpdatedDGCoordinates(double[] completeChangeRate)
 {
     // Standard case: Just add completeChangeRate to DGCoordinates as array
     double[] upDGC = new double[Mapping.LocalLength];
     DGCoordinates.CopyTo(upDGC, 0);
     upDGC = OrderValuesBySgrd(upDGC);
     BLAS.daxpy(upDGC.Length, -1, OrderValuesBySgrd(completeChangeRate), 1, upDGC, 1);
     return(upDGC);
 }
コード例 #2
0
ファイル: RungeKutta.cs プロジェクト: octwanna/BoSSS
        /// <summary>
        /// performs one timestep
        /// </summary>
        /// <param name="dt">size of timestep</param>
        public override double Perform(double dt)
        {
            using (var tr = new ilPSP.Tracing.FuncTrace()) {
                if (TimeStepConstraints != null)
                {
                    dt = CalculateTimeStep();
                }

                double[][] k = new double[m_Scheme.Stages][];
                for (int i = 0; i < m_Scheme.Stages; i++)
                {
                    k[i] = new double[Mapping.LocalLength];
                }

                double[] y0 = new double[Mapping.LocalLength];
                DGCoordinates.CopyTo(y0, 0);

                // logging
                tr.Info("Runge-Kutta Scheme with " + m_Scheme.Stages + " stages.");
                double time0 = m_Time;
                tr.Info("time = " + time0 + ", dt = " + dt);

                // berechne k[0]
                ComputeChangeRate(k[0], m_Time, 0);// invokes MPI communication

                for (int s = 1; s < m_Scheme.Stages; s++)
                {
                    PerformStage(y0, s, k, dt);

                    m_Time = time0 + m_Scheme.c[s] * dt;
                    ComputeChangeRate(k[s], m_Time, m_Scheme.c[s] * dt);// invokes MPI communication
                }

                // next timestep
                DGCoordinates.Clear();
                DGCoordinates.CopyFrom(y0, 0);
                Array.Clear(y0, 0, y0.Length);
                for (int s = 0; s < m_Scheme.Stages; s++)
                {
                    if (m_Scheme.b[s] != 0.0)
                    {
                        BLAS.daxpy(y0.Length, -m_Scheme.b[s] * dt, k[s], 1, y0, 1);
                    }
                }
                DGCoordinates.axpy <double[]>(y0, 1.0);
                base.ApplyFilter(dt);

                m_Time = time0 + dt;
            }
            return(dt);
        }
コード例 #3
0
        private void RKstage(double dt, double[][] k, int s, BlockMsrMatrix MsInv, BlockMsrMatrix M0, double[] u0, double[] coefficients)
        {
            // Copy coordinates to temp array since SpMV (below) does not
            // support in-place computation
            double[] tempCoordinates = DGCoordinates.ToArray();
            M0.SpMV(1.0, u0, 0.0, tempCoordinates); // Non-agglomerated
            for (int l = 0; l < s; l++)
            {
                tempCoordinates.AccV(-coefficients[l] * dt, k[l]); // Non-agglomerated
            }

            speciesMap.Agglomerator.ManipulateRHS(tempCoordinates, Mapping);
            MsInv.SpMV(1.0, tempCoordinates, 0.0, DGCoordinates);
            speciesMap.Agglomerator.Extrapolate(DGCoordinates.Mapping);
        }
コード例 #4
0
        public override double Perform(double dt)
        {
            if (TimeStepConstraints != null)
            {
                dt = CalculateTimeStep();
            }

            int NoOfStages = this.Scheme.Stages;

            double[][] k = new double[NoOfStages][];

            Mapping.Fields.ForEach(f => f.Clear(speciesMap.SubGrid.VolumeMask.Complement()));
            UpdateEvaluatorsAndMasks();
            AgglomerateAndExtrapolateDGCoordinates();

            BlockMsrMatrix M0 = speciesMap.GetMassMatrixFactory(Mapping).NonAgglomeratedMassMatrix;

            double[] u0 = DGCoordinates.ToArray(); // Lives on non-agglomerated mesh

            // Initialize RK scheme
            k[0] = new double[Mapping.LocalLength];
            ComputeChangeRate(k[0], Time, 0.0);

            // Intermediate stages
            for (int stage = 1; stage < NoOfStages; stage++)
            {
                MoveLevelSetTo(Time + dt * this.Scheme.c[stage]);
                UpdateEvaluatorsAndMasks();
                AgglomerateAndExtrapolateDGCoordinates();

                BlockMsrMatrix MsInverse = speciesMap.GetMassMatrixFactory(Mapping).InverseMassMatrix;
                RKstage(dt, k, stage, MsInverse, M0, u0, this.Scheme.a.GetRow(stage));

                k[stage] = new double[Mapping.LocalLength];
                ComputeChangeRate(k[stage], Time, this.Scheme.c[stage] * dt);
            }

            // Final stage
            MoveLevelSetTo(Time + dt);
            UpdateEvaluatorsAndMasks();

            BlockMsrMatrix M1Inverse = speciesMap.GetMassMatrixFactory(Mapping).InverseMassMatrix;

            RKstage(dt, k, NoOfStages, M1Inverse, M0, u0, this.Scheme.b);

            m_Time = Time + dt;
            return(dt);
        }
コード例 #5
0
ファイル: IBMABevolve.cs プロジェクト: octwanna/BoSSS
        protected override double[] ComputesUpdatedDGCoordinates(double[] completeChangeRate)
        {
            double[] y0 = new double[Mapping.LocalLength];
            DGCoordinates.CopyTo(y0, 0);
            DGCoordinates.axpy <double[]>(completeChangeRate, -1);

            // Speciality for IBM: Do the extrapolation
            speciesMap.Agglomerator.Extrapolate(DGCoordinates.Mapping);

            double[] upDGC = DGCoordinates.ToArray();
            upDGC = OrderValuesBySgrd(upDGC);
            // DGCoordinates should be untouched after calling this method
            DGCoordinates.Clear();
            DGCoordinates.CopyFrom(y0, 0);

            return(upDGC);
        }
コード例 #6
0
        /// <summary>
        /// performs one Explicit Euler timestep
        /// </summary>
        /// <param name="dt">size of timestep</param>
        public virtual double Perform(double dt)
        {
            using (new ilPSP.Tracing.FuncTrace()) {
                if (TimeStepConstraints != null)
                {
                    dt = CalculateTimeStep();
                }
                double[] k = new double[Mapping.LocalLength];
                ComputeChangeRate(k, m_Time, 0);
                DGCoordinates.axpy <double[]>(k, -dt);

                ApplyFilter(dt);

                m_Time += dt;
            }
            return(dt);
        }
コード例 #7
0
ファイル: RungeKutta.cs プロジェクト: octwanna/BoSSS
        /// <summary>
        /// Performs a single stage of a timestep.
        /// </summary>
        /// <param name="y0">Initial DG coordinates</param>
        /// <param name="s">The current stage</param>
        /// <param name="k">The current change rate</param>
        /// <param name="dt">The size of the timestep</param>
        protected virtual void PerformStage(double[] y0, int s, double[][] k, double dt)
        {
            DGCoordinates.Clear();
            DGCoordinates.axpy <double[]>(y0, 1.0);
            double relTime = 0;

            for (int r = 0; r < s; r++)
            {
                if (m_Scheme.a[s, r] != 0.0)
                {
                    DGCoordinates.axpy <double[]>(k[r], -dt * m_Scheme.a[s, r]);
                    relTime += dt * m_Scheme.a[s, r];
                }
            }

            base.ApplyFilter(dt * relTime);
        }
コード例 #8
0
ファイル: AdamsBashforthLTS.cs プロジェクト: octwanna/BoSSS
        /// <summary>
        /// Performs a time step
        /// </summary>
        /// <param name="dt">Time step size that equals -1, if no fixed time step is prescribed</param>
        public override double Perform(double dt)
        {
            using (new ilPSP.Tracing.FuncTrace()) {
                if (ABevolver[0].HistoryChangeRate.Count >= order - 1)
                {
                    bool reclustered = false;
                    if (adaptive)
                    {
                        if (timestepNumber % reclusteringInterval == 0)
                        {
                            // Fix for update problem of artificial viscosity
                            RaiseOnBeforeComputechangeRate(Time, dt);

                            Clusterer.Clustering oldClustering = CurrentClustering;

                            // Necessary in order to use the number of sub-grids specified by the user for the reclustering in each time step
                            // Otherwise the value could be changed by the constructor of the parent class (AdamsBashforthLTS.cs) --> CreateSubGrids()
                            CurrentClustering = clusterer.CreateClustering(numberOfClustersInitial, this.SubGrid);

                            CurrentClustering = CalculateNumberOfLocalTS(CurrentClustering); // Might remove sub-grids when time step sizes are too similar
                            reclustered       = clusterer.CheckForNewClustering(oldClustering, CurrentClustering);

                            // After the intitial phase, activate adaptive mode for all ABevolve objects
                            foreach (ABevolve abE in ABevolver)
                            {
                                abE.adaptive = true;
                            }

                            if (reclustered)
                            {
                                ShortenHistories(ABevolver);
                                ABevolve[] oldABevolver = ABevolver;
                                CreateNewABevolver();
                                CopyHistoriesOfABevolver(oldABevolver);
                            }

                            GetBoundaryTopology();
#if DEBUG
                            if (reclustered)
                            {
                                Console.WriteLine("RECLUSTERING");
                            }
#endif
                        }
                    }

                    // Number of substeps could have changed
                    if (TimeStepConstraints != null)
                    {
                        dt = CalculateTimeStep();
                    }

                    double[,] CorrectionMatrix = new double[CurrentClustering.NumberOfClusters, CurrentClustering.NumberOfClusters];

                    // Saves the results at t_n
                    double[] y0 = new double[Mapping.LocalLength];
                    DGCoordinates.CopyTo(y0, 0);

                    double time0 = m_Time;
                    double time1 = m_Time + dt;

                    TimestepNumber subTimestep = new TimestepNumber(timestepNumber - 1);

                    // Evolves each sub-grid with its own time step (only one step)
                    // (The result is not written to m_DGCoordinates!)
                    for (int i = 0; i < ABevolver.Length; i++)
                    {
                        //localABevolve[i].completeBndFluxes.Clear();
                        //if (localABevolve[i].completeBndFluxes.Any(x => x != 0.0)) Console.WriteLine("Not all Bnd fluxes were used in correction step!!!");
                        ABevolver[i].Perform(dt / (double)NumberOfLocalTimeSteps[i]);
                    }

                    // After evolving each cell update the time with dt_min
                    m_Time = m_Time + dt / (double)NumberOfLocalTimeSteps[CurrentClustering.NumberOfClusters - 1];

                    if (saveToDBCallback != null)
                    {
                        subTimestep = subTimestep.NextIteration();
                        saveToDBCallback(subTimestep, m_Time);
                    }

                    // Saves the history of DG_Coordinates for each cluster
                    Queue <double[]>[] historyDGC_Q = new Queue <double[]> [CurrentClustering.NumberOfClusters];
                    for (int i = 0; i < historyDGC_Q.Length; i++)
                    {
                        historyDGC_Q[i] = ABevolver[i].HistoryDGCoordinate;
                    }

                    if (!adaptive)
                    {
                        // Saves DtHistory for each cluster
                        historyTime_Q = new Queue <double> [CurrentClustering.NumberOfClusters];
                        for (int i = 0; i < historyTime_Q.Length; i++)
                        {
                            historyTime_Q[i] = ABevolver[i].HistoryTime;
                        }
                    }

                    // Perform the local time steps
                    for (int localTS = 1; localTS < NumberOfLocalTimeSteps.Last(); localTS++)
                    {
                        for (int id = 1; id < CurrentClustering.NumberOfClusters; id++)
                        {
                            //Evolve Condition: Is "ABevolve.Time" at "AB_LTS.Time"?
                            if ((ABevolver[id].Time - m_Time) < 1e-10)
                            {
                                double localDt = dt / NumberOfLocalTimeSteps[id];

                                foreach (Chunk chunk in CurrentClustering.Clusters[id].VolumeMask)
                                {
                                    foreach (int cell in chunk.Elements)
                                    {
                                        // f == each field
                                        // n == basis polynomial
                                        foreach (DGField f in Mapping.Fields)
                                        {
                                            for (int n = 0; n < f.Basis.GetLength(cell); n++)
                                            {
                                                int coordinateIndex = Mapping.LocalUniqueCoordinateIndex(f, cell, n);
                                                DGCoordinates[coordinateIndex] = historyDGC_Q[id].Last()[coordinateIndex];
                                            }
                                        }
                                    }
                                }

                                Dictionary <int, double> myDic = InterpolateBoundaryValues(historyDGC_Q, id, ABevolver[id].Time);

                                foreach (KeyValuePair <int, double> kvp in myDic)
                                {
                                    DGCoordinates[kvp.Key] = kvp.Value;
                                }

                                ABevolver[id].Perform(localDt);

                                m_Time = ABevolver.Min(s => s.Time);

                                if (saveToDBCallback != null)
                                {
                                    subTimestep = subTimestep.NextIteration();
                                    saveToDBCallback(subTimestep, m_Time);
                                }
                            }

                            // Are we at an (intermediate-) syncronization levels?
                            // For conservatvity, we have to correct the values of the larger cell cluster
                            if (fluxCorrection)
                            {
                                for (int idCoarse = 0; idCoarse < id; idCoarse++)
                                {
                                    if (Math.Abs(ABevolver[id].Time - ABevolver[idCoarse].Time) < 1e-10 &&
                                        !(Math.Abs(ABevolver[idCoarse].Time - CorrectionMatrix[idCoarse, id]) < 1e-10))
                                    {
                                        if (fluxCorrection)
                                        {
                                            CorrectFluxes(idCoarse, id, historyDGC_Q);
                                        }
                                        CorrectionMatrix[idCoarse, id] = ABevolver[idCoarse].Time;
                                    }
                                }
                            }
                        }
                    }

                    // Finalize step
                    // Use unmodified values in history of DGCoordinates (DGCoordinates could have been modified by
                    // InterpolateBoundaryValues, should be resetted afterwards)
                    DGCoordinates.Clear();
                    for (int id = 0; id < historyDGC_Q.Length; id++)
                    {
                        DGCoordinates.axpy <double[]>(historyDGC_Q[id].Last(), 1);
                    }

                    // Update time
                    m_Time = time0 + dt;
                }
                else
                {
                    double[] currentChangeRate = new double[Mapping.LocalLength];
                    double[] upDGC             = new double[Mapping.LocalLength];

                    // Save time history
                    if (adaptive)
                    {
                        for (int i = 0; i < ABevolver.Length; i++)
                        {
                            double[] currentTime = new double[ABevolver[i].ABSubGrid.LocalNoOfCells];
                            for (int j = 0; j < currentTime.Length; j++)
                            {
                                currentTime[j] = m_Time;
                            }
                            ABevolver[i].historyTimePerCell.Enqueue(currentTime);
                        }
                    }
                    else
                    {
                        if (ABevolver[0].HistoryTime.Count == 0)
                        {
                            for (int i = 0; i < ABevolver.Length; i++)
                            {
                                ABevolver[i].HistoryTime.Enqueue(m_Time);
                            }
                        }
                    }

                    // Needed for the history
                    for (int i = 0; i < CurrentClustering.NumberOfClusters; i++)
                    {
                        double[] localCurrentChangeRate = new double[currentChangeRate.Length];
                        double[] edgeFlux = new double[gridData.iGeomEdges.Count * Mapping.Fields.Count];
                        ABevolver[i].ComputeChangeRate(localCurrentChangeRate, m_Time, 0, edgeFlux);
                        ABevolver[i].HistoryChangeRate.Enqueue(localCurrentChangeRate);
                        ABevolver[i].HistoryBoundaryFluxes.Enqueue(edgeFlux);
                    }

                    dt = RungeKuttaScheme.Perform(dt);

                    DGCoordinates.CopyTo(upDGC, 0);

                    // Saves ChangeRateHistory for AB LTS
                    // Only entries for the specific cluster
                    for (int i = 0; i < CurrentClustering.NumberOfClusters; i++)
                    {
                        ABevolver[i].HistoryDGCoordinate.Enqueue(OrderValuesByCluster(CurrentClustering.Clusters[i], upDGC));
                        if (!adaptive)
                        {
                            ABevolver[i].HistoryTime.Enqueue(RungeKuttaScheme.Time);
                        }
                    }

                    // RK is a global timeStep
                    // -> time update for all other timeStepper with rk.Time
                    m_Time = RungeKuttaScheme.Time;
                    foreach (ABevolve ab in ABevolver)
                    {
                        ab.ResetTime(m_Time, timestepNumber);
                    }
                }
            }

            if (adaptive)
            {
                timestepNumber++;
            }

            return(dt);
        }
コード例 #9
0
ファイル: AdamsBashforth.cs プロジェクト: octwanna/BoSSS
        /// <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
                    DGCoordinates.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);
        }