/// <summary> /// Test if the matrix is symmetric positive definite /// </summary> /// <returns>bool array res=[symmetry, positive definit]</returns> public bool[] Symmetry() { bool[] res = new bool[2]; //extract submatrix for selected dependent variables int[] DepVars = this.VarGroup; double[] DepVars_subvec = this.m_map.GetSubvectorIndices(true, DepVars).Select(i => i + 1.0).ToArray(); //MsrMatrix OpMtxMSR = m_OpMtx.ToMsrMatrix(); int[] SubMatrixIdx_Row = m_map.GetSubvectorIndices(false, DepVars); int[] SubMatrixIdx_Cols = m_map.GetSubvectorIndices(false, DepVars); int L = SubMatrixIdx_Row.Length; MsrMatrix SubOpMtx = new MsrMatrix(L, L, 1, 1); m_OpMtx.WriteSubMatrixTo(SubOpMtx, SubMatrixIdx_Row, default(int[]), SubMatrixIdx_Cols, default(int[])); // symmetry test by calculation of symmetry deviation bool sym = false; double SymmDev = m_OpMtx.SymmetryDeviation(); if (SymmDev < 1e-5) { sym = true; } res[0] = sym; // positive definite test by Cholesky decomposition var FullyPopulatedMatrix = m_OpMtx.ToFullMatrixOnProc0(); bool posDef = true; // only proc 0 gets info so the following is executed exclusively on rank 0 if (ilPSP.Environment.MPIEnv.MPI_Rank == 0) { try { FullyPopulatedMatrix.Cholesky(); } catch (ArithmeticException) { posDef = false; } } res[1] = MPIEnviroment.Broadcast <bool>(posDef, 0, ilPSP.Environment.MPIEnv.Mpi_comm); Debug.Assert(res[0].MPIEquals(), "value does not match on procs"); Debug.Assert(res[1].MPIEquals(), "value does not match on procs"); return(res); }
/// <summary> /// Test code for debugging. /// </summary> /// <param name="OperatorsFlowField"></param> /// <param name="VelocityMapping"></param> /// <param name="VelocityVectorMapping"></param> private void SaveMatricesToTextFile(OperatorFactoryFlowFieldVariableDensity OperatorsFlowField, UnsetteledCoordinateMapping VelocityMapping, UnsetteledCoordinateMapping VelocityVectorMapping) { OperatorsFlowField.Swip2[0].OperatorMatrix.SaveToTextFileSparse("C:\\tmp\\Swip20.txt"); OperatorsFlowField.Swip2[1].OperatorMatrix.SaveToTextFileSparse("C:\\tmp\\Swip21.txt"); OperatorsFlowField.Swip3[0].OperatorMatrix.SaveToTextFileSparse("C:\\tmp\\Swip30.txt"); OperatorsFlowField.Swip3[1].OperatorMatrix.SaveToTextFileSparse("C:\\tmp\\Swip31.txt"); ViscSplit[0, 0].AssemblyMatrix.SaveToTextFileSparse("C:\\tmp\\ViscSplit00.txt"); ViscSplit[0, 1].AssemblyMatrix.SaveToTextFileSparse("C:\\tmp\\ViscSplit01.txt"); ViscSplit[1, 0].AssemblyMatrix.SaveToTextFileSparse("C:\\tmp\\ViscSplit10.txt"); ViscSplit[1, 1].AssemblyMatrix.SaveToTextFileSparse("C:\\tmp\\ViscSplit11.txt"); int[] IndicesVelocity = VelocityMapping.GetSubvectorIndices(true, 0); int[] IndicesVelocityVector0 = VelocityVectorMapping.GetSubvectorIndices(true, 0); int[] IndicesVelocityVector1 = VelocityVectorMapping.GetSubvectorIndices(true, 1); MsrMatrix Swip2Mtx = new MsrMatrix(VelocityVectorMapping); OperatorsFlowField.Swip2[0].OperatorMatrix.WriteSubMatrixTo <IList <int>, IList <int>, IList <int>, IList <int> >(Swip2Mtx, IndicesVelocity, IndicesVelocityVector0, IndicesVelocityVector0, IndicesVelocityVector0); OperatorsFlowField.Swip2[0].OperatorMatrix.AccSubMatrixTo <IList <int>, IList <int>, IList <int>, IList <int> >(1.0, Swip2Mtx, IndicesVelocity, IndicesVelocityVector0, IndicesVelocityVector1, IndicesVelocityVector1); OperatorsFlowField.Swip2[1].OperatorMatrix.AccSubMatrixTo <IList <int>, IList <int>, IList <int>, IList <int> >(1.0, Swip2Mtx, IndicesVelocity, IndicesVelocityVector1, IndicesVelocityVector0, IndicesVelocityVector0); OperatorsFlowField.Swip2[1].OperatorMatrix.AccSubMatrixTo <IList <int>, IList <int>, IList <int>, IList <int> >(1.0, Swip2Mtx, IndicesVelocity, IndicesVelocityVector1, IndicesVelocityVector1, IndicesVelocityVector1); Swip2Mtx.SaveToTextFileSparse("C:\\tmp\\Swip2.txt"); }
/// <summary> /// Ctor. /// </summary> /// <param name="Swip2"></param> /// <param name="Swip3">Can be null for multiphase flows.</param> /// <param name="Component">Component of velocity vector.</param> /// <param name="VelocityMapping"></param> /// <param name="VelocityVectorMapping"></param> public MatrixAssemblyViscSplit(SIMPLEOperator Swip2, SIMPLEOperator Swip3, int Component, UnsetteledCoordinateMapping VelocityMapping, UnsetteledCoordinateMapping VelocityVectorMapping) : base(false, false) { this.Swip2 = Swip2; this.Swip3 = Swip3; RowIndicesSource = new int[Swip2.LocalLength]; int i0 = Swip2.RowPartition.i0; for (int i = 0; i < Swip2.LocalLength; i++) { RowIndicesSource[i] = i + i0; } ColumnIndicesSource = VelocityVectorMapping.GetSubvectorIndices(true, Component); ColumnIndicesTarget = VelocityMapping.GetSubvectorIndices(true, 0); base.Initialize(); }
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[])); }
/// <summary> /// Tests if a matrix (associated with some operator) depends only on values in this sub-grid, /// or not. /// </summary> /// <param name="_Mtx">some operator matrix</param> /// <param name="RowMap">row-/co-domain mapping for matrix <paramref name="_Mtx"/></param> /// <param name="ColMap">column/domain mapping for matrix <paramref name="_Mtx"/></param> /// <param name="NoOfTests"></param> /// <returns> /// 0.0 if there is no dependency of the matrix <paramref name="_Mtx"/> /// on values outside of this subgrid. /// </returns> public double TestMatrixDependency(MsrMatrix _Mtx, UnsetteledCoordinateMapping RowMap, UnsetteledCoordinateMapping ColMap, int NoOfTests = 10) { Random RND = new Random(); if (!_Mtx.RowPartitioning.Equals(RowMap)) { throw new ArgumentException(); } if (!_Mtx.ColPartition.Equals(ColMap)) { throw new ArgumentException(); } var Mtx = new ilPSP.LinSolvers.monkey.CPU.RefMatrix(_Mtx); int[] IR = RowMap.BasisS.Count.ForLoop(i => i); int[] IC = ColMap.BasisS.Count.ForLoop(i => i); var SgrdRow = RowMap.GetSubvectorIndices(this, true, IR); var SgrdCol = SgrdRow; // ColMap.GetSubvectorIndices(this, true, true, IC); double[] X0 = new double[ColMap.LocalLength]; double[] Y0 = new double[RowMap.LocalLength]; for (int i = 0; i < X0.Length; i++) { X0[i] = RND.NextDouble(); } Mtx.SpMV(1.0, X0, 0.0, Y0); int i0Row = RowMap.i0; int i0Col = ColMap.i0; int iECol = ColMap.iE; double err = 0; for (int iTest = 0; iTest < NoOfTests; iTest++) { double[] X1 = new double[ColMap.LocalLength]; double[] Y1 = new double[RowMap.LocalLength]; for (int i = 0; i < X0.Length; i++) { X1[i] = RND.NextDouble(); } foreach (int i in SgrdCol) { if (i >= i0Col && i < iECol) { X1[i - i0Col] = X0[i - i0Col]; } } Mtx.SpMV(1.0, X1, 0.0, Y1); foreach (int k in SgrdRow) { double Y1k = Y1[k - i0Row]; double Y0k = Y0[k - i0Row]; //Debug.Assert((Y0k - Y1k).Pow2() < 1.0e-8); err += (Y0k - Y1k).Pow2(); } } return(err.MPISum()); }