/// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        protected override MsrMatrix ComputeMatrix()
        {
            MsrMatrix CorrectorMatrix = new MsrMatrix(m_IPOperator.OperatorMatrix);

            switch (m_SolverConf.Control.Algorithm)
            {
            case SolutionAlgorithms.Steady_SIMPLE:
                break;

            case SolutionAlgorithms.Unsteady_SIMPLE:
                // gamma * dt / (beta_0 + gamma * dt)
                double UnsteadyFactor = m_BDF.gamma[m_SolverConf.BDFOrder - 1] * m_SolverConf.dt / (m_BDF.beta[m_SolverConf.BDFOrder - 1][0] + m_BDF.gamma[m_SolverConf.BDFOrder - 1] * m_SolverConf.dt);
                CorrectorMatrix.Scale(UnsteadyFactor);
                break;

            default:
                throw new NotImplementedException();
            }

            if (m_PressureStabilization != null)
            {
                CorrectorMatrix.Acc(-1.0, m_PressureStabilization.OperatorMatrix);
            }

            CorrectorMatrix.AssumeSymmetric = true;
            return(CorrectorMatrix);
        }
Beispiel #2
0
        public void ImplicitEuler(double dt, SubGrid S, SinglePhaseField inout_Levset)
        {
            var VolMsk = S.VolumeMask;
            var EdgMsk = S.InnerEdgesMask;
            UnsetteledCoordinateMapping Map = inout_Levset.Mapping;

            if (dt <= 0.0)
            {
                throw new ArgumentOutOfRangeException("Timestep size must be greater than 0.");
            }

            MsrMatrix Pmtx = PenaltyMatrix(EdgMsk, inout_Levset.Basis, inout_Levset.Basis);

            Pmtx.Scale(-1.0);

            int[] SubVecIdx = Map.GetSubvectorIndices(S, true, new int[] { 0 });
            int   L         = SubVecIdx.Length;

            MsrMatrix SubMtx = new MsrMatrix(L, L);

            Pmtx.AccSubMatrixTo(1.0, SubMtx, SubVecIdx, default(int[]), SubVecIdx, default(int[]));

            SubMtx.AccEyeSp(1.0 / dt);

            double[] RHS = new double[L];
            double[] SOL = new double[L];

            RHS.AccV(1.0 / dt, inout_Levset.CoordinateVector, default(int[]), SubVecIdx);

            using (var solver = new PARDISOSolver()) {
                solver.DefineMatrix(SubMtx);
                solver.Solve(SOL, RHS);
            }

            inout_Levset.CoordinateVector.ClearEntries(SubVecIdx);
            inout_Levset.CoordinateVector.AccV(1.0, SOL, SubVecIdx, default(int[]));
        }
Beispiel #3
0
        public SolverResult Solve <Tdiag, Tunknowns, Trhs>(double Scale, Tdiag d, Tunknowns x, Trhs rhs)
            where Tdiag : System.Collections.Generic.IList <double>
            where Tunknowns : System.Collections.Generic.IList <double>
            where Trhs : System.Collections.Generic.IList <double>
        {
            using (var tr = new FuncTrace()) {
                // check input arguments
                // =====================

                if (x.Count != m_OrgMatrix.RowPartitioning.LocalLength)
                {
                    throw new ArgumentException("length of x must be equal to matrix size.");
                }
                if (rhs.Count != m_OrgMatrix.RowPartitioning.LocalLength)
                {
                    throw new ArgumentException("length of rhs must be equal to matrix size.");
                }
                if (Math.Abs(Scale) <= double.Epsilon)
                {
                    throw new ArgumentException("scale to small.");
                }

                // prepare vectors
                // ===============
                double[] _x;
                double[] _rhs;
                if (x.GetType() == typeof(double[]))
                {
                    _x = x as double[];
                }
                else
                {
                    _x = new double[x.Count];
                }
                if (rhs.GetType() == typeof(double[]))
                {
                    _rhs = (double[])((ICloneable)rhs).Clone();
                }
                else
                {
                    int L = m_MumpsMatrix.RowPart.LocalLength;
                    _rhs = new double[L];
                    for (int i = 0; i < L; i++)
                    {
                        _rhs[i] = rhs[i];
                    }
                }

                // define matrix
                // =============

                IMutableMatrixEx Mtx;
                //bool throwAwayMtx;
                if (d != null || Scale != 1.0)
                {
                    // not very efficient, but _I_dont_care_ !

                    MsrMatrix _Mtx = new MsrMatrix(m_OrgMatrix);
                    Mtx = _Mtx;
                    _Mtx.Scale(Scale);

                    int dLen = d.Count, L = _Mtx.RowPartitioning.LocalLength, i0 = (int)(_Mtx.RowPartitioning.i0);
                    if ((L % dLen) != 0)
                    {
                        throw new ApplicationException("wrong length of 'd'.");
                    }

                    for (int l = 0; l < L; l++)
                    {
                        _Mtx[i0 + l, i0 + l] += d[l % dLen];
                    }

                    //throwAwayMtx = true;
                }
                else
                {
                    //throwAwayMtx = false;
                    Mtx = m_OrgMatrix;
                }

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

                SolverResult r = new SolverResult();
                using (new BlockTrace("CALL SOLVER", tr)) {
                    r.Converged      = true;
                    r.NoOfIterations = 1;
                    Stopwatch st = new Stopwatch();
                    st.Reset();

                    double[] gath_x, gath_b;
                    GatherOnProc0(_x, _rhs, out gath_x, out gath_b);

                    r.NoOfIterations = 1;
                    int rank; int size;
                    csMPI.Raw.Comm_Rank(this.m_MPI_Comm, out rank);
                    csMPI.Raw.Comm_Size(this.m_MPI_Comm, out size);

                    r.Converged = MUMPSInitAndSolve(m_OrgMatrix, gath_b);

                    csMPI.Raw.Barrier(this.m_MPI_Comm);
                    unsafe
                    {
                        bool snd = r.Converged;
                        csMPI.Raw.Bcast((IntPtr)(&snd), 1, csMPI.Raw._DATATYPE.BYTE, 0, this.m_MPI_Comm);
                        r.Converged = snd;
                    }

                    ScatterFromProc0(_x, gath_b);

                    if (x.GetType() == typeof(double[]))
                    {
                        // do nothing
                    }
                    else
                    {
                        x.SetV(_x);
                    }


                    csMPI.Raw.Barrier(this.m_MPI_Comm);

                    st.Stop();

                    r.RunTime = st.Elapsed;
                }
                return(r);
            }
        }