private void ApproximationMatrix() { this.Aapprox = null; this.AapproxInverse = null; //MsrMatrix AapproxComp = null; /* * switch(m_SIMPLEOptions.Option_Approximation_Predictor) { * case ApproxPredictor.MassMatrix: * case ApproxPredictor.LocalizedOperator: { break; } * default: { * Aapprox = ConvDiff.CloneAs(); * //switch (m_SIMPLEOptions.Option_Timestepper) { * // case Timestepper.Steady: break; * // case Timestepper.ImplicitEuler: { * // Aapprox.Acc(1.0 / dt, MassMatrix); * // break; * // } * // default: { * // throw new NotImplementedException("Unknown Timestepper"); * // } * //} * AapproxComp = new MsrMatrix(USubMatrixIdx.Length, USubMatrixIdx.Length, MassMatrix.RowPartitioning.BlockSize / (2 * D), MassMatrix.ColPartition.BlockSize / (2 * D)); * Aapprox.WriteSubMatrixTo(AapproxComp, USubMatrixIdx, default(int[]), USubMatrixIdx, default(int[])); * break; * } * } */ switch (m_SIMPLEOptions.Option_Approximation_Predictor) { case ApproxPredictor.MassMatrix: { BlockMsrMatrix MM; if (!double.IsPositiveInfinity(this.m_SIMPLEOptions.dt)) { // instationary SIMPLE //MM = this.m_MgOp.MassMatrix.CloneAs(); // hier muss ich mir nochmal was überlegen -- // für einige Präkond.-Optionen // (genau jene, welche die XDG-Basen für beide Phasen in Cut-Zellen mischen), // wie etwa // MultigridOperator.Mode.SymPart_DiagBlockEquilib // ist eine Block-Skalierung mit rho_A und rho_B // inkonsistent! // throw new NotImplementedException("todo"); } else { MM = this.m_MgOp.MassMatrix; } Aapprox = new MsrMatrix(this.ConvDiff.RowPartitioning); this.m_MgOp.MassMatrix.WriteSubMatrixTo(Aapprox, this.USubMatrixIdx_Row, default(int[]), this.USubMatrixIdx_Row, default(int[])); //AapproxInverse = MassMatrixInv._ToMsrMatrix();// Aapprox.Invert(); //switch(m_SIMPLEOptions.Option_Timestepper) { // case Timestepper.Steady: break; // case Timestepper.ImplicitEuler: { // Aapprox.Scale(1 + 1.0 / dt); // AapproxInverse.Scale(1 / (1 + 1.0 / dt)); // /*#if DEBUG // var CheckMX = AapproxInverse * Aapprox; // foreach (int i in USubMatrixIdx) { // if (Math.Abs(CheckMX.GetDiagonalElement(i) - 1.0) > 1e-10) throw new ArithmeticException("AapproxInverse is not the Inverse of the Aapprox-Matrix"); // } // #endif*/ // break; // } // default: { // throw new NotImplementedException("Unknown Timestepper"); // } //} break; } case ApproxPredictor.Exact: { if (this.LsTrk.GridDat.CellPartitioning.MpiSize > 1) { throw new NotSupportedException("Not implemented for MPI-parallel runs."); } //RowIdx = VelocityMapping.GetSubvectorIndices(this.LsTrk, D.ForLoop(d => d), _SpcIds: this.LsTrk.SpeciesIdS, drk: this.TransportAgglomerator); //ColIdx = RowIdx; if (USubMatrixIdx_Row.Length > 4500) { Console.WriteLine(string.Format("WARNING: you don't really want to invert a {0}x{0} matrix.", USubMatrixIdx_Row.Length)); } this.Aapprox = this.ConvDiff; MultidimensionalArray AapproxFull = Aapprox.ToFullMatrixOnProc0(); MultidimensionalArray AapproxInverseFull = AapproxFull.GetInverse(); this.AapproxInverse = new MsrMatrix(new Partitioning(USubMatrixIdx_Row.Length)); this.AapproxInverse.AccDenseMatrix(1.0, AapproxInverseFull); break; } case ApproxPredictor.Diagonal: { /* * Aapprox = new MsrMatrix(ConvDiff.RowPartitioning, ConvDiff.ColPartition); * AapproxInverse = new MsrMatrix(ConvDiff.RowPartitioning, ConvDiff.ColPartition); * foreach(int i in USubMatrixIdx) { * int[] j = new int[] { i }; * double Value = ConvDiff.GetValues(i, j)[0]; * //Value += MassMatrix.GetValues(i, j)[0]; * Aapprox.SetDiagonalElement(i, Value); * if(Value == 0) { * AapproxInverse.SetDiagonalElement(i, 0); * } else { * AapproxInverse.SetDiagonalElement(i, 1 / Value); * } * } #if DEBUG * Aapprox.VerifyDataStructure(); * AapproxInverse.VerifyDataStructure(); * var CheckMX = AapproxInverse * Aapprox; * foreach(int i in USubMatrixIdx) { * if(Math.Abs(CheckMX.GetDiagonalElement(i) - 1.0) > 1e-13) throw new ArithmeticException("AapproxInverse is not the Inverse of the Operator Matrix"); * } #endif * break; */ throw new NotImplementedException("todo"); } case ApproxPredictor.BlockDiagonal: { /* * AapproxInverse = new MsrMatrix(Aapprox.RowPartitioning, Aapprox.ColPartition); * var AapproxCompBD = new BlockDiagonalMatrix(AapproxComp); * var AapproxCompInvBD = AapproxCompBD.Invert(); * AapproxCompBD._ToMsrMatrix().WriteSubMatrixTo(Aapprox, default(int[]), USubMatrixIdx, default(int[]), USubMatrixIdx); * AapproxCompInvBD._ToMsrMatrix().WriteSubMatrixTo(AapproxInverse, default(int[]), USubMatrixIdx, default(int[]), USubMatrixIdx); * //#if DEBUG * Aapprox.VerifyDataStructure(); * AapproxInverse.VerifyDataStructure(); * var CheckMX = AapproxInverse * Aapprox; * foreach(int i in USubMatrixIdx) { * if(Math.Abs(CheckMX.GetDiagonalElement(i) - 1.0) > 1e-12) throw new ArithmeticException("AapproxInverse is not the Inverse of the Operator Matrix"); * } * //#endif * * break; */ throw new NotImplementedException("todo"); } case ApproxPredictor.BlockSum: { /* * Console.WriteLine("BlockSum is not properly tested yet and did not work in previous tests"); * int AccdBlockSize = ConvDiff.RowPartitioning.BlockSize / (2 * D); * var AapproxBD = new BlockDiagonalMatrix(ConvDiff.RowPartitioning); * var Aapprox = new MsrMatrix(ConvDiff.RowPartitioning); * int[] indexer = new int[AccdBlockSize]; * for(int i = 0; i < indexer.Length; i++) { * indexer[i] = i; * } * int[] rowindexer = indexer.CloneAs(); * * * for(int i = 0; i < ConvDiff.NoOfRows / AccdBlockSize; i++) { * int[] colindexer = indexer.CloneAs(); * for(int j = 0; j < ConvDiff.NoOfCols / AccdBlockSize; j++) { * ConvDiff.AccSubMatrixTo(1.0, Aapprox, rowindexer, rowindexer, colindexer, rowindexer); * for(int r = 0; r < indexer.Length; r++) { * colindexer[r] += AccdBlockSize; * } * } * for(int r = 0; r < indexer.Length; r++) { * rowindexer[r] += AccdBlockSize; * } * } * //if (m_SIMPLEOptions.Option_Timestepper == Timestepper.ImplicitEuler) { * // Aapprox.Acc(1 / dt, MassMatrix); * //} * AapproxComp = new MsrMatrix(USubMatrixIdx.Length, USubMatrixIdx.Length, AccdBlockSize, AccdBlockSize); * Aapprox.WriteSubMatrixTo(AapproxComp, USubMatrixIdx, default(int[]), USubMatrixIdx, default(int[])); * AapproxInverse = new MsrMatrix(Aapprox.RowPartitioning, Aapprox.ColPartition); * var AapproxCompBD = new BlockDiagonalMatrix(AapproxComp); * var AapproxCompInvBD = AapproxCompBD.Invert(); * AapproxCompInvBD._ToMsrMatrix().WriteSubMatrixTo(AapproxInverse, default(int[]), USubMatrixIdx, default(int[]), USubMatrixIdx); #if DEBUG * Aapprox.VerifyDataStructure(); * AapproxInverse.VerifyDataStructure(); * * // Check copying back and forth * var CheckAapproxComp = new MsrMatrix(Aapprox.RowPartitioning, Aapprox.ColPartition); * AapproxComp.WriteSubMatrixTo(CheckAapproxComp, default(int[]), USubMatrixIdx, default(int[]), USubMatrixIdx); * CheckAapproxComp.Acc(-1.0, Aapprox); * if(CheckAapproxComp.InfNorm() > 1e-14) throw new ArithmeticException("Something went wrong while copying the Aapprox Matrix"); * * //Check Transformation to BlockdiagonalMatrix * var CheckAapproxCompBD = new MsrMatrix(Aapprox.RowPartitioning, Aapprox.ColPartition); * AapproxCompBD._ToMsrMatrix().WriteSubMatrixTo(CheckAapproxCompBD, default(int[]), USubMatrixIdx, default(int[]), USubMatrixIdx); * CheckAapproxCompBD.Acc(-1.0, Aapprox); * if(CheckAapproxCompBD.InfNorm() > 1e-14) throw new ArithmeticException("Something went wrong while copying the Aapprox Matrix"); * * //Check Matrix Inversion * var CheckMX = AapproxInverse * Aapprox; * foreach(int i in USubMatrixIdx) { * if(Math.Abs(CheckMX.GetDiagonalElement(i) - 1.0) > 1e-12) throw new ArithmeticException("AapproxInverse is not the Inverse of the Operator Matrix"); * } #endif * break; */ throw new NotImplementedException("todo"); } case ApproxPredictor.Neumann: { /* * Console.WriteLine("Neumann did not work in previous Tests, Series does typically not converge"); * int serieslength = 10; * * Aapprox = ConvDiff.CloneAs(); * //if (m_SIMPLEOptions.Option_Timestepper != Timestepper.Steady) { * // Aapprox.Acc(1.0 / dt, MassMatrix); * //} * var B = Aapprox.CloneAs(); * double ScalingFactor = Aapprox.InfNorm(); * B.Scale((-1.0 / ScalingFactor.Pow(0))); //Scaling Power up to 4 tried * B.AccEyeSp(1.0); * AapproxInverse = B; * AapproxInverse.AccEyeSp(1.0); * MsrMatrix OldMoment = B; * for(int i = 0; i <= serieslength; i++) { * var NewMoment = OldMoment * B; * AapproxInverse.Acc(1.0, NewMoment); * //Debug * Console.WriteLine("MomentNumber #{0}, InfNormOf Inverse #{1}", i, NewMoment.InfNorm()); * OldMoment = NewMoment; * } * AapproxInverse.Scale((1.0 / ScalingFactor.Pow(0))); //Scaling Power up to 4 tried * break; */ throw new NotImplementedException("todo"); } case ApproxPredictor.LocalizedOperator: { /* * Console.WriteLine("Localized Operator did not work in previous Tests"); * double[] LocalizedOpAffine; * MultiphaseCellAgglomerator LocalizedAgglomerator; * Aapprox = new MsrMatrix(MassMatrix.RowPartitioning, MassMatrix.ColPartition); * TransportOpLocalized.AssembleMatrix( * out Aapprox, out LocalizedOpAffine, * out LocalizedAgglomerator, out TransportMassFact, * this.Velocity.Current, null, * this.LevSet, null, Curv, * VelocityMapping, VelocityMapping); * if(Option_Timestepper == Timestepper.ImplicitEuler) { * Aapprox.Acc(1 / dt, MassMatrix); * } * * var DiagAverage = Aapprox.GetDiagVector().Average(); * foreach(int i in RowIdx) { * if(Aapprox.GetDiagonalElement(i) == 0.0) { * //Aapprox.SetDiagonalElement(i, MassMatrix.GetDiagonalElement(i)); * Aapprox.SetDiagonalElement(i, DiagAverage); * } * } * AapproxComp = new MsrMatrix(RowIdx.Length, RowIdx.Length, MassMatrix.RowPartitioning.BlockSize / (2 * D), MassMatrix.ColPartition.BlockSize / (2 * D)); * Aapprox.WriteSubMatrixTo(AapproxComp, RowIdx, default(int[]), ColIdx, default(int[])); * AapproxInverse = new MsrMatrix(Aapprox.RowPartitioning, Aapprox.ColPartition); * var AapproxCompBD = new BlockDiagonalMatrix(AapproxComp); * var AapproxCompInvBD = AapproxCompBD.Invert(); * AapproxCompInvBD._ToMsrMatrix().WriteSubMatrixTo(AapproxInverse, default(int[]), RowIdx, default(int[]), ColIdx); * //AapproxComp._ToMsrMatrix().WriteSubMatrixTo(Aapprox, default(int[]), RowIdx, default(int[]), ColIdx); * * #if DEBUG * Aapprox.VerifyDataStructure(); * AapproxInverse.VerifyDataStructure(); * var CheckAapproxCompBD = new MsrMatrix(Aapprox.RowPartitioning, Aapprox.ColPartition); * AapproxCompBD._ToMsrMatrix().WriteSubMatrixTo(CheckAapproxCompBD, default(int[]), RowIdx, default(int[]), ColIdx); * CheckAapproxCompBD.Acc(-1.0, Aapprox); * if(CheckAapproxCompBD.InfNorm() > 1e-14) throw new ArithmeticException("Something went wrong while copying the Aapprox Matrix"); * var CheckMX = AapproxInverse * Aapprox; * foreach(int i in RowIdx) { * if(Math.Abs(CheckMX.GetDiagonalElement(i) - 1.0) > 1e-12) throw new ArithmeticException("AapproxInverse is not the Inverse of the Operator Matrix"); * } #endif * break; */ throw new NotImplementedException("todo"); } default: throw new NotImplementedException("todo"); } if (this.AapproxInverse == null) { // block-inversion is required. // ++++++++++++++++++++++++++++ int D = this.LsTrk.GridDat.SpatialDimension; this.AapproxInverse = new MsrMatrix(this.Aapprox.RowPartitioning, this.Aapprox.ColPartition); //int N = this.m_MgOp.Mapping.AggBasis.GetMinimalLength(this.m_MgOp.Mapping.DgDegree[0]); //Debug.Assert(this.Aapprox.RowPartitioning.LocalLength % N == 0); MultidimensionalArray Block = new MultidimensionalArray(2); MultidimensionalArray InvBlock = new MultidimensionalArray(2); int iRow0 = this.Aapprox.RowPartitioning.i0; int JAGG = this.m_MgOp.Mapping.AggGrid.iLogicalCells.NoOfLocalUpdatedCells; int[] DegreeS = this.m_MgOp.Mapping.DgDegree; for (int jagg = 0; jagg < JAGG; jagg++) // loop over aggregate cells... { for (int d = 0; d < D; d++) // loop over velocity components... { int N = this.m_MgOp.Mapping.AggBasis[d].GetLength(jagg, DegreeS[d]); if (Block.GetLength(0) != N) { Block.Allocate(N, N); InvBlock.Allocate(N, N); } for (int n = 0; n < N; n++) { #if DEBUG int iRow = iRow0 + n; { int[] Cols = null; double[] Vals = null; int LR = Aapprox.GetRow(iRow, ref Cols, ref Vals); int cMin = int.MaxValue; int cMax = int.MinValue; for (int lr = 0; lr < LR; lr++) { if (Vals[lr] != 0.0) { cMin = Math.Min(cMin, Cols[lr]); cMax = Math.Max(cMax, Cols[lr]); } } Debug.Assert(cMin >= iRow0); Debug.Assert(cMax < iRow0 + N); } #endif for (int m = 0; m < N; m++) { Block[n, m] = this.Aapprox[iRow0 + n, iRow0 + m]; } } Block.InvertTo(InvBlock); for (int n = 0; n < N; n++) { for (int m = 0; m < N; m++) { this.AapproxInverse[iRow0 + n, iRow0 + m] = InvBlock[n, m]; } } iRow0 += N; } } Debug.Assert(iRow0 == this.Aapprox.RowPartitioning.iE); } #if DEBUG var CheckMX = AapproxInverse * Aapprox; double TRESH = Math.Max(AapproxInverse.InfNorm(), Aapprox.InfNorm()) * 1.0e-10; for (int iRow = CheckMX.RowPartitioning.i0; iRow < CheckMX.RowPartitioning.iE; iRow++) { if (Math.Abs(CheckMX.GetDiagonalElement(iRow) - 1.0) > TRESH) { throw new ArithmeticException("AapproxInverse is not the Inverse of the Aapprox-Matrix"); } } #endif }
/// <summary> /// Spatial operator matrix analysis method /// </summary> public void SpatialOperatorMatrixAnalysis(bool CheckAssertions, int AnalysisLevel) { using (var solver = new Rheology()) { int D = solver.Grid.SpatialDimension; if (AnalysisLevel < 0 || AnalysisLevel > 2) { throw new ArgumentException(); } BlockMsrMatrix OpMatrix; double[] OpAffine; solver.AssembleMatrix(out OpMatrix, out OpAffine, solver.CurrentSolution.Mapping.ToArray(), true); // ============================= // AnalysisLevel 0 // ============================= { var OpMatrixT = OpMatrix.Transpose(); CoordinateVector TestVec = new CoordinateVector(solver.CurrentSolution.Mapping.Fields.Select(f => f.CloneAs()).ToArray()); double testsumPos = 0.0; double testsumNeg = 0.0; for (int rnd_seed = 0; rnd_seed < 20; rnd_seed++) { // fill the pressure components of the test vector TestVec.Clear(); Random rnd = new Random(rnd_seed); DGField Pressack = TestVec.Mapping.Fields[D] as DGField; int J = solver.GridData.iLogicalCells.NoOfLocalUpdatedCells; for (int j = 0; j < J; j++) { int N = Pressack.Basis.GetLength(j); for (int n = 0; n < N; n++) { Pressack.Coordinates[j, n] = rnd.NextDouble(); } } // Gradient times P: double[] R1 = new double[TestVec.Count]; OpMatrix.SpMV(1.0, TestVec, 0.0, R1); // R1 = Grad * P //Console.WriteLine("L2 of 'Grad * P': " + R1.L2Norm()); // transpose of Divergence times P: double[] R2 = new double[TestVec.Count]; OpMatrix.SpMV(1.0, TestVec, 0.0, R2); // R2 = divT * P //Console.WriteLine("L2 of 'divT * P': " + R2.L2Norm()); TestVec.Clear(); TestVec.Acc(1.0, R1); TestVec.Acc(1.0, R2); // analyze! testsumNeg += GenericBlas.L2Dist(R1, R2); R2.ScaleV(-1.0); testsumPos += GenericBlas.L2Dist(R1, R2); } Console.WriteLine("Pressure/Divergence Symmetry error in all tests (+): " + testsumPos); Console.WriteLine("Pressure/Divergence Symmetry error in all tests (-): " + testsumNeg); if (CheckAssertions) { Assert.LessOrEqual(Math.Abs(testsumNeg), testsumPos * 1.0e-13); } } // ============================= // AnalysisLevel 1 and 2 // ============================= if (AnalysisLevel > 0) { AggregationGridBasis[][] MgBasis = AggregationGridBasis.CreateSequence(solver.MultigridSequence, solver.CurrentSolution.Mapping.BasisS); MultigridOperator mgOp = new MultigridOperator(MgBasis, solver.CurrentSolution.Mapping, OpMatrix, null, solver.MultigridOperatorConfig); // extract //////////// MsrMatrix FullMatrix = mgOp.OperatorMatrix.ToMsrMatrix(); MsrMatrix DiffMatrix; { int[] VelVarIdx = D.ForLoop(d => d); int[] USubMatrixIdx_Row = mgOp.Mapping.GetSubvectorIndices(VelVarIdx); int[] USubMatrixIdx_Col = mgOp.Mapping.GetSubvectorIndices(VelVarIdx); int L = USubMatrixIdx_Row.Length; DiffMatrix = new MsrMatrix(L, L, 1, 1); FullMatrix.WriteSubMatrixTo(DiffMatrix, USubMatrixIdx_Row, default(int[]), USubMatrixIdx_Col, default(int[])); double DiffMatrix_sd = DiffMatrix.SymmetryDeviation(); Console.WriteLine("Diffusion assymetry:" + DiffMatrix_sd); } MsrMatrix SaddlePointMatrix; { int[] VelPVarIdx = new int[] { 0, 1, 2 }; int[] VelPSubMatrixIdx_Row = mgOp.Mapping.GetSubvectorIndices(VelPVarIdx); int[] VelPSubMatrixIdx_Col = mgOp.Mapping.GetSubvectorIndices(VelPVarIdx); int L = VelPSubMatrixIdx_Row.Length; SaddlePointMatrix = new MsrMatrix(L, L, 1, 1); FullMatrix.WriteSubMatrixTo(SaddlePointMatrix, VelPSubMatrixIdx_Row, default(int[]), VelPSubMatrixIdx_Col, default(int[])); } //SaddlePointMatrix.SaveToTextFileSparse("C:\\Users\\kikker\\Documents\\MATLAB\\spm.txt"); MsrMatrix ConstitutiveMatrix; { int[] StressVarIdx = new int[] { 3, 4, 5 }; int[] StressSubMatrixIdx_Row = mgOp.Mapping.GetSubvectorIndices(StressVarIdx); int[] StressSubMatrixIdx_Col = mgOp.Mapping.GetSubvectorIndices(StressVarIdx); int L = StressSubMatrixIdx_Row.Length; ConstitutiveMatrix = new MsrMatrix(L, L, 1, 1); FullMatrix.WriteSubMatrixTo(ConstitutiveMatrix, StressSubMatrixIdx_Row, default(int[]), StressSubMatrixIdx_Col, default(int[])); } // operator analysis ////////////////////// bool posDef; if (AnalysisLevel > 1) { // +++++++++++++++++++++++++++++++ // check condition number, etc // +++++++++++++++++++++++++++++++ MultidimensionalArray ret = MultidimensionalArray.Create(1, 5); Console.WriteLine("Calling MATLAB/Octave..."); using (BatchmodeConnector bmc = new BatchmodeConnector()) { bmc.PutSparseMatrix(FullMatrix, "FullMatrix"); bmc.PutSparseMatrix(SaddlePointMatrix, "SaddlePointMatrix"); bmc.PutSparseMatrix(ConstitutiveMatrix, "ConstitutiveMatrix"); bmc.PutSparseMatrix(DiffMatrix, "DiffMatrix"); bmc.Cmd("DiffMatrix = 0.5*(DiffMatrix + DiffMatrix');"); bmc.Cmd("condNoFullMatrix = condest(FullMatrix);"); bmc.Cmd("condNoSaddlePointMatrix = condest(SaddlePointMatrix);"); bmc.Cmd("condNoConstitutiveMatrix = condest(ConstitutiveMatrix);"); bmc.Cmd("condNoDiffMatrix = condest(DiffMatrix);"); //bmc.Cmd("eigiMaxiSaddle = 1.0; % eigs(SaddlePointMatrix,1,'lm')"); //bmc.Cmd("eigiMiniSaddle = 1.0; % eigs(SaddlePointMatrix,1,'sm')"); //bmc.Cmd("eigiMaxiConst = 1.0; % eigs(ConstitutiveMatrix,1,'lm')"); //bmc.Cmd("eigiMiniConst = 1.0; % eigs(ConstitutiveMatrix,1,'sm')"); //bmc.Cmd("eigiMaxiDiff = 1.0; % eigs(DiffMatrix,1,'lm')"); //bmc.Cmd("eigiMiniDiff = 1.0; % eigs(DiffMatrix,1,'sm')"); bmc.Cmd("lasterr"); bmc.Cmd("[V,r]=chol(SaddlePointMatrix);"); bmc.Cmd("[V,r]=chol(ConstitutiveMatrix);"); bmc.Cmd("ret = [condNoFullMatrix, condNoSaddlePointMatrix, condNoConstitutiveMatrix, condNoDiffMatrix, r]"); //eigiMaxiSaddle, eigiMiniSaddle, eigiMaxiConst, eigiMiniConst, eigiMaxiDiff, eigiMiniDiff, bmc.GetMatrix(ret, "ret"); bmc.Execute(false); } double condNoFullMatrix = ret[0, 0]; double condNoSaddlePMatrix = ret[0, 1]; double condNoConstitutiveMatrix = ret[0, 2]; double condNoDiffMatrix = ret[0, 3]; //double eigiMaxiSaddle = ret[0, 4]; //double eigiMiniSaddle = ret[0, 5]; //double eigiMaxiConst = ret[0, 6]; //double eigiMiniConst = ret[0, 7]; //double eigiMaxiDiff = ret[0, 8]; //double eigiMiniDiff = ret[0, 9]; posDef = ret[0, 4] == 0; //Console.WriteLine("Eigenvalue range of saddle point matrix: {0} to {1}", eigiMiniSaddle, eigiMaxiSaddle); //Console.WriteLine("Eigenvalue range of constitutive matrix: {0} to {1}", eigiMiniConst, eigiMaxiConst); //Console.WriteLine("Eigenvalue range of diffusion matrix: {0} to {1}", eigiMiniDiff, eigiMaxiDiff); Console.WriteLine("Condition number full operator: {0:0.####E-00}", condNoFullMatrix); Console.WriteLine("Condition number saddle point operator: {0:0.####E-00}", condNoSaddlePMatrix); Console.WriteLine("Condition number constitutive operator: {0:0.####E-00}", condNoConstitutiveMatrix); Console.WriteLine("Condition number diffusion operator: {0:0.####E-00}", condNoDiffMatrix); //base.QueryHandler.ValueQuery("ConditionNumber", condNoFullMatrix); } else { // +++++++++++++++++++++++++++++++++++++++ // test only for positive definiteness // +++++++++++++++++++++++++++++++++++++++ var SaddlePMatrixFull = SaddlePointMatrix.ToFullMatrixOnProc0(); var ConstMatrixFull = ConstitutiveMatrix.ToFullMatrixOnProc0(); posDef = true; try { SaddlePMatrixFull.Cholesky(); } catch (ArithmeticException) { posDef = false; } posDef = true; try { ConstMatrixFull.Cholesky(); } catch (ArithmeticException) { posDef = false; } } double SaddlePSymm = SaddlePointMatrix.SymmetryDeviation(); Console.WriteLine("Symmetry deviation of saddle point matrix: " + SaddlePSymm); if (posDef) { Console.WriteLine("Good news: Saddle point operator matrix seems to be positive definite."); } else { Console.WriteLine("WARNING: Saddle point operator matrix is not positive definite."); } double ConstSymm = ConstitutiveMatrix.SymmetryDeviation(); Console.WriteLine("Symmetry deviation of constitutive matrix: " + ConstSymm); if (posDef) { Console.WriteLine("Good news: constitutive operator matrix seems to be positive definite."); } else { Console.WriteLine("WARNING: constitutive operator matrix is not positive definite."); } //if (CheckAssertions) { // if (Control.AdvancedDiscretizationOptions.ViscosityMode == ViscosityMode.FullySymmetric && Control.PhysicalParameters.IncludeConvection == false) { // Assert.IsTrue(posDef, "Positive definiteness test failed."); // double compVal = DiffMatrix.InfNorm() * 1e-13; // Assert.LessOrEqual(DiffSymm, compVal, "Diffusion matrix seems to be non-symmetric."); // } //} } } }