Beispiel #1
0
        /// <summary>
        /// Solves the linear system (diag(1/<paramref name="dt"/>) +
        /// <em>M</em>) * x =
        /// <see cref="ImplicitTimeStepper.CurrentState"/> /
        /// <paramref name="dt"/> -
        /// <see cref="ImplicitTimeStepper.m_AffineOffset1"/> and writes the
        /// result to <see cref="ImplicitTimeStepper.CurrentState"/>.
        /// </summary>
        /// <param name="dt">The length of the timestep</param>
        protected override void PerformTimeStep(double dt)
        {
            using (var tr = new ilPSP.Tracing.FuncTrace()) {
                int n  = Mapping.LocalLength;
                int np = m_diagVecOneSec.Length;

                double[] diag = new double[n];
                for (int i = 0; i < n; i++)
                {
                    diag[i] = m_diagVecOneSec[i % np];
                }
                BLAS.dscal(n, 1.0 / dt, diag, 1);

                double[] rhs = (double[])m_AffineOffset1.Clone();
                BLAS.dscal(n, -1.0, rhs, 1);

                for (int i = 0; i < n; i++)
                {
                    rhs[i] += diag[i] * CurrentState[i];
                }

                tr.Info("Calling solver");
                LastSolverResult = m_Solver.Solve <double[], CoordinateVector, double[]>(1.0, diag, CurrentState, rhs);
            }
        }
Beispiel #2
0
        /// <summary>
        /// computes the change rate for the time evolution problem;
        /// </summary>
        /// <param name="k">
        /// the "change rate" is <b>accumulated</b> here;<br/>
        /// Indices into this array can be computed by <see cref="Mapping"/>;
        /// </param>
        /// <param name="AbsTime">
        /// absolute time at which the change rate will be evaluated
        /// </param>
        /// <param name="RelTime">
        /// time, relative to the point of time at which the initial value holds.
        /// </param>
        /// <remarks>
        /// Assume an ODE
        /// <br/>
        /// d/dt u = f(u)
        /// <br/>
        /// which is discretized by an explicit Euler scheme
        /// <br/>
        /// (u_1 - u_0)/delta_t = f(u_0).
        /// <br/>
        /// Here, f(u) denotes the discretization of the spatial operator by the DG method.
        /// The purpose of this method is to evaluate f(u_0).<br/>
        /// It does so by calling <see cref="SpatialOperator.Evaluator.Evaluate{Tout}"/>
        /// of <see cref="Evaluator"/>.<br/>
        /// Override this method e.g. for the implementation of (some types of) limiters.
        /// </remarks>
        virtual internal protected void ComputeChangeRate(double[] k, double AbsTime, double RelTime, double[] edgeFluxes = null)
        {
            using (var tr = new ilPSP.Tracing.FuncTrace()) {
                RaiseOnBeforeComputechangeRate(AbsTime, RelTime);

                // k += F(u0)
                Evaluator.Evaluate <double[]>(1.0, 1.0, k, AbsTime, outputBndEdge: edgeFluxes);
            }
        }
Beispiel #3
0
        /// <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];
                CurrentState.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
                CurrentState.Clear();
                CurrentState.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);
                    }
                }
                CurrentState.axpy <double[]>(y0, 1.0);
                base.ApplyFilter(dt);

                m_Time = time0 + dt;
            }
            return(dt);
        }
Beispiel #4
0
        /// <summary>
        /// solves the equation system;
        /// there is no solution output,
        /// the solution is written to the fields in <see cref="Mapping"/>;
        /// </summary>
        /// <param name="rhs">optional right-hand-side, can be null;</param>
        /// <returns>the basic statistics of the sparse solver</returns>
        /// <remarks>
        /// If an right-hand-side operator has been specified, i.e.
        /// <see cref="RhsEvaluator"/> is not null, it is evaluated prior
        /// to the sparse solver call;
        /// The result of this right-hand-side operator, added to <paramref name="rhs"/>,
        /// can be monitored by consuming the <see cref="RHSEvaluated"/>-event.
        /// </remarks>
        virtual public SolverResult Solve(IList <double> rhs)
        {
            // initial stuff
            // =============

            using (var tr = new ilPSP.Tracing.FuncTrace()) {
                // prepare right-hand-side
                // =======================

                // clone or allocate memory
                double[] _rhs;
                GetTotalRHS(rhs, out _rhs);

                //// testcode
                //{
                //    Field f = new SinglePhaseField(m_Context, new Basis(m_Context, 2));

                //    int J = f.Coordinates.NoOfRows;
                //    int N = f.Coordinates.NoOfCols;
                //    int cnt = 0;
                //    for( int j = 0; j < J; j++)
                //        for (int nn = 0; nn < N; nn++) {
                //            f.Coordinates[j, nn] = _rhs[cnt];
                //            cnt++;
                //        }

                //    double InfNrm = f.LinfNorm();
                //    double TwoNorm = f.L2Norm();

                //    Console.WriteLine("rhs L2: " + TwoNorm + " inf: " + InfNrm);


                //    //Array.Copy(_rhs, f.Coordinates.C, _rhs.Length);
                //    BoSSS.Solution.Tecplot.Tecplot.PlotFields(new Field[] { f }, null, m_Context, "rhs", "---", 0, 0);
                //}

                // call solver
                // ===========

                tr.Info("entering linear solver:");
                SolverResult ret = m_Solver.Solve <CoordinateVector, double[]>(m_DGCoordinates, (double[])_rhs.Clone());
                tr.Info("no. of iterations: " + ret.NoOfIterations);
                tr.Info("converged? : " + ret.Converged);
                tr.Info("Pure solver runtime: " + ret.RunTime.TotalSeconds + " sec.");

                // finalize
                // ========
                return(ret);
            }
        }
Beispiel #5
0
        /*
         * /// <summary>
         * /// Solves the linear system (diag(1/<paramref name="dt"/>) +
         * /// <em>M</em>) * x =
         * /// <see cref=" SubgridMapping.subgridCoordinates"/> /
         * /// <paramref name="dt"/> -
         * /// <see cref="ImplicitTimeStepper.m_AffineOffset1"/> and writes the
         * /// result to <see cref=" SubgridMapping.subgridCoordinates"/>.
         * /// </summary>
         * /// <param name="dt">The lenght of the timestep</param>
         * protected override void PerformTimeStep(double dt) {
         *  using (var tr = new ilPSP.Tracing.FuncTrace()) {
         *
         *      int n = SubgridMapping.SubgridNUpdate * SubgridMapping.MaxTotalNoOfCoordinatesPerCell;
         *
         *      double[] rhs = (double[])m_CompressedAffine.Clone();
         *      BLAS.dscal(rhs.Length, -1.0, rhs, 1);
         *
         *      for (int i = 0; i < n; i++) {
         *          rhs[i] += 1.0 / dt * SubgridDGCoordinates[i];
         *      }
         *
         *      tr.Info("Calling solver");
         *
         *      LastSolverResult = m_Solver.Solve<double[], double[]>(SubgridDGCoordinates, rhs);
         *      //Console.WriteLine(LastSolverResult.NoOfIterations);
         *      SubgridMapping.subgridCoordinates = SubgridDGCoordinates;
         *
         *  }
         * }*/
        protected override void PerformTimeStep(double dt)
        {
            using (var tr = new ilPSP.Tracing.FuncTrace()) {
                int[] cells = m_Subgrid.SubgridIndex2LocalCellIndex;
                // int n = SubgridMapping.SubgridNUpdate * SubgridMapping.MaxTotalNoOfCoordinatesPerCell;
                int      CoordinateOffset = 0;
                double[] rhs = (double[])m_CompressedAffine.Clone();
                //     BLAS.dscal(rhs.Length, -1.0, rhs, 1);

                /*  for (int j = 0; j < cells.Length; j++) {
                 *    CoordinateOffset = 0;
                 *    for (int g = 0; g < temporalOp.Length; g++) {
                 *
                 *        if (temporalOp[g]) {*/


                for (int g = 0; g < temporalOp.Length; g++)
                {
                    if (temporalOp[g])
                    {
                        for (int j = 0; j < cells.Length; j++)
                        {
                            int loc = j * m_SubgridMapping.MaxTotalNoOfCoordinatesPerCell + CoordinateOffset;
                            for (int i = 0; i < m_SubgridMapping.Fields[g].Basis.MaximalLength; i++)
                            {
                                rhs[loc] += 1.0 / dt * SubgridDGCoordinates[loc];
                                loc++;
                            }
                        }
                    }
                    CoordinateOffset += m_SubgridMapping.Fields[g].Basis.MaximalLength;
                }

                tr.Info("Calling solver");

                LastSolverResult = m_Solver.Solve <double[], double[]>(SubgridDGCoordinates, rhs);
                SubgridMapping.subgridCoordinates = SubgridDGCoordinates;
                Console.WriteLine("Solver" + LastSolverResult.NoOfIterations);
                if (LastSolverResult.Converged)
                {
                    Console.WriteLine("SolverConverged?:Yes");
                }
                else
                {
                    Console.WriteLine("SolverConverged?:No");
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// performs one timestep
        /// </summary>
        /// <param name="dt">size of timestep</param>
        public override void Perform(double dt)
        {
            using (var tr = new ilPSP.Tracing.FuncTrace()) {
                double[][] k = new double[m_RKscheme.Stages][];
                for (int i = 0; i < m_RKscheme.Stages; i++)
                {
                    k[i] = new double[m_SubgridMapping.subgridCoordinates.Length];
                }

                double[] y0 = new double[m_SubgridMapping.subgridCoordinates.Length];
                m_DGCoordinates.CopyTo(y0, 0);

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

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

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

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

                // next timestep

                y0.CopyTo(m_DGCoordinates, 0);
                Array.Clear(y0, 0, y0.Length);
                for (int s = 0; s < m_RKscheme.Stages; s++)
                {
                    BLAS.daxpy(y0.Length, -m_RKscheme.b[s] * dt, k[s], 1, y0, 1);
                }
                //m_DGCoordinates.axpy<double[]>(y0, 1.0);
                BLAS.daxpy(m_DGCoordinates.Length, 1.0, y0, 1, m_DGCoordinates, 1);
                m_Time = time0 + dt;
            }
        }
Beispiel #7
0
        /// <summary>
        /// Solves the linear system (diag(1/<paramref name="dt"/>) +
        /// <em>M</em> / 2) * x =
        /// <see cref="ImplicitTimeStepper.CurrentState"/> /
        /// <paramref name="dt"/> -
        /// <em>M</em> *
        /// <see cref="ImplicitTimeStepper.CurrentState"/> / 2 -
        /// 0.5*(<see cref="ImplicitTimeStepper.m_AffineOffset1"/> +
        /// <see cref="m_AffineOffset0"/> )
        /// and writes the
        /// result do <see cref="ImplicitTimeStepper.CurrentState"/>.
        /// </summary>
        /// <param name="dt">The length of the timestep</param>
        protected override void PerformTimeStep(double dt)
        {
            using (var tr = new ilPSP.Tracing.FuncTrace()) {
                if (m_Theta <= 0 || m_Theta > 1)
                {
                    throw new ApplicationException("m_Theta out of range; must be betwwen 0.0 (including) and 1.0 (including), but m_Theta = " + m_Theta);
                }

                int n  = Mapping.LocalLength;
                int np = m_diagVecOneSec.Length;

                double[] diag = new double[n];
                for (int i = 0; i < n; i++)
                {
                    diag[i] = m_diagVecOneSec[i % np];
                }
                BLAS.dscal(n, 1.0 / (m_Theta * dt), diag, 1);

                double[] rhs;
                if (m_AffineOffset0 != null)
                {
                    rhs = m_AffineOffset0;
                    BLAS.dscal(rhs.Length, -(1.0 - m_Theta) / m_Theta, rhs, 1);
                    BLAS.daxpy(rhs.Length, -1.0, m_AffineOffset1, 1, rhs, 1);
                }
                else
                {
                    rhs = (double[])m_AffineOffset1.Clone();
                }

                if (m_Theta != 1.0)
                {
                    // if m_Theta == 0.0, this has no effect and is a waste of comp. power
                    ISparseMatrix eM = m_Solver.GetMatrix();
                    eM.SpMV <CoordinateVector, double[]>(-(1.0 - m_Theta) / m_Theta, CurrentState, 1.0, rhs);
                }

                for (int i = 0; i < n; i++)
                {
                    rhs[i] += diag[i] * CurrentState[i];
                    // fraglich
                }

                tr.Info("Calling solver");
                LastSolverResult = m_Solver.Solve <double[], CoordinateVector, double[]>(1.0, diag, CurrentState, rhs);
                tr.Info("no. of iterations: " + LastSolverResult.NoOfIterations);
                tr.Info("converged? : " + LastSolverResult.Converged);
                tr.Info("Pure solver runtime: " + LastSolverResult.RunTime.TotalSeconds + " sec.");


                /*
                 * int n = Mapping.LocalLength;
                 * int np = m_diagVecOneSec.Length;
                 *
                 * double[] diag = new double[n];
                 * for (int i = 0; i < n; i++) {
                 *  diag[i] = m_diagVecOneSec[i % np];
                 * }
                 * BLAS.dscal(n, 1.0 / dt, diag, 1);
                 *
                 * double[] rhs = (double[])m_AffineOffset1.Clone();
                 * BLAS.dscal(n, -1.0, rhs, 1);
                 *
                 * for (int i = 0; i < n; i++) {
                 *  rhs[i] += diag[i] * DGCoordinates[i];
                 * }
                 *
                 * m_Context.IOMaster.tracer.Message(ht, "Calling solver");
                 * LastSolverResult = m_Solver.Solve<double[], CoordinateVector, double[]>(1.0, diag, DGCoordinates, rhs);
                 */
            }
        }
Beispiel #8
0
        /// <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);
        }