/// <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); }
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[])); }
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); } }