protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { using (FuncTrace tr = new FuncTrace()) { // assemble system, create matrix // ------------------------------ var volQrSch = new CellQuadratureScheme(true, CellMask.GetFullMask(this.GridData)); var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetFullMask(this.GridData)); double D = this.GridData.SpatialDimension; double penalty_base = (T.Basis.Degree + 1) * (T.Basis.Degree + D) / D; double penalty_factor = base.Control.penalty_poisson; { // equation assembly // ----------------- tr.Info("creating sparse system..."); Console.WriteLine("creating sparse system for {0} DOF's ...", T.Mapping.Ntotal); Stopwatch stw = new Stopwatch(); stw.Start(); SpatialOperator LapaceIp = new SpatialOperator(1, 1, QuadOrderFunc.SumOfMaxDegrees(), "T", "T"); var flux = new ipFlux(penalty_base * base.Control.penalty_poisson, this.GridData.Cells.cj, base.Control); LapaceIp.EquationComponents["T"].Add(flux); LapaceIp.Commit(); #if DEBUG var RefLaplaceMtx = new MsrMatrix(T.Mapping); #endif LaplaceMtx = new BlockMsrMatrix(T.Mapping); LaplaceAffine = new double[T.Mapping.LocalLength]; LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping, LaplaceMtx, LaplaceAffine, volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch); #if DEBUG LaplaceAffine.ClearEntries(); LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping, RefLaplaceMtx, LaplaceAffine, volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch); MsrMatrix ErrMtx = RefLaplaceMtx.CloneAs(); ErrMtx.Acc(-1.0, LaplaceMtx); double err = ErrMtx.InfNorm(); double infNrm = LaplaceMtx.InfNorm(); Console.WriteLine("Matrix comparison error: " + err + ", matrix norm is: " + infNrm); Assert.Less(err, infNrm * 1e-10, "MsrMatrix2 comparison failed."); #endif //int q = LaplaceMtx._GetTotalNoOfNonZeros(); //tr.Info("finished: Number of non-zeros: " + q); stw.Stop(); Console.WriteLine("done {0} sec.", stw.Elapsed.TotalSeconds); //double condNo = LaplaceMtx.condest(BatchmodeConnector.Flavor.Octave); //Console.WriteLine("condition number: {0:0.####E-00} ",condNo); } } }
protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt) { //phystime = 1.8; LsUpdate(phystime); // operator-matrix assemblieren OperatorMatrix = new BlockMsrMatrix(ProblemMapping); AltOperatorMatrix = new MsrMatrix(ProblemMapping); double[] Affine = new double[OperatorMatrix.RowPartitioning.LocalLength]; MultiphaseCellAgglomerator Agg; // Agglomerator setup //Agg = new MultiphaseCellAgglomerator(new CutCellMetrics(MomentFittingVariant, m_quadOrder, LsTrk, LsTrk.GetSpeciesId("B")), this.THRESHOLD, false); Agg = LsTrk.GetAgglomerator(new SpeciesId[] { LsTrk.GetSpeciesId("B") }, m_quadOrder, __AgglomerationTreshold: this.THRESHOLD); Console.WriteLine("Inter-Process agglomeration? " + Agg.GetAgglomerator(LsTrk.GetSpeciesId("B")).AggInfo.InterProcessAgglomeration); // operator matrix assembly //Op.ComputeMatrixEx(LsTrk, // ProblemMapping, null, ProblemMapping, // OperatorMatrix, Affine, false, 0.0, true, // Agg.CellLengthScales, null, null, // LsTrk.SpeciesIdS.ToArray()); XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Op.GetMatrixBuilder(base.LsTrk, ProblemMapping, null, ProblemMapping, LsTrk.SpeciesIdS.ToArray()); mtxBuilder.time = 0.0; mtxBuilder.ComputeMatrix(OperatorMatrix, Affine); Agg.ManipulateMatrixAndRHS(OperatorMatrix, Affine, this.ProblemMapping, this.ProblemMapping); //Op.ComputeMatrixEx(LsTrk, // ProblemMapping, null, ProblemMapping, // AltOperatorMatrix, Affine, false, 0.0, true, // Agg.CellLengthScales, null, null, // LsTrk.SpeciesIdS.ToArray()); mtxBuilder.ComputeMatrix(AltOperatorMatrix, Affine); Agg.ManipulateMatrixAndRHS(AltOperatorMatrix, Affine, this.ProblemMapping, this.ProblemMapping); int nnz = this.OperatorMatrix.GetTotalNoOfNonZeros(); Console.WriteLine("Number of non-zeros in matrix: " + nnz); int nnz2 = this.AltOperatorMatrix.GetTotalNoOfNonZeros(); Assert.IsTrue(nnz == nnz2, "Number of non-zeros in matrix different for " + OperatorMatrix.GetType() + " and " + AltOperatorMatrix.GetType()); Console.WriteLine("Number of non-zeros in matrix (reference): " + nnz2); MsrMatrix Comp = AltOperatorMatrix.CloneAs(); Comp.Acc(-1.0, OperatorMatrix); double CompErr = Comp.InfNorm(); double Denom = Math.Max(AltOperatorMatrix.InfNorm(), OperatorMatrix.InfNorm()); double CompErrRel = Denom > Math.Sqrt(double.Epsilon) ? CompErr / Denom : CompErr; Console.WriteLine("Comparison: " + CompErrRel); Assert.LessOrEqual(CompErrRel, 1.0e-7, "Huge difference between MsrMatrix and BlockMsrMatrix."); base.TerminationKey = true; return(0.0); }
/// <summary> /// computes <see cref="LaplaceMtx"/> and <see cref="LaplaceAffine"/> /// </summary> private void UpdateMatrices() { using (var tr = new FuncTrace()) { // time measurement for matrix assembly Stopwatch stw = new Stopwatch(); stw.Start(); // console Console.WriteLine("creating sparse system for {0} DOF's ...", T.Mapping.Ntotal); // quadrature domain var volQrSch = new CellQuadratureScheme(true, CellMask.GetFullMask(this.GridData, MaskType.Geometrical)); var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetFullMask(this.GridData, MaskType.Geometrical)); #if DEBUG // in DEBUG mode, we compare 'MsrMatrix' (old, reference implementation) and 'BlockMsrMatrix' (new standard) var RefLaplaceMtx = new MsrMatrix(T.Mapping); #endif using (new BlockTrace("SipMatrixAssembly", tr)) { LaplaceMtx = new BlockMsrMatrix(T.Mapping); LaplaceAffine = new double[T.Mapping.LocalLength]; LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping, LaplaceMtx, LaplaceAffine, volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch); } #if DEBUG LaplaceAffine.ClearEntries(); LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping, RefLaplaceMtx, LaplaceAffine, volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch); MsrMatrix ErrMtx = RefLaplaceMtx.CloneAs(); ErrMtx.Acc(-1.0, LaplaceMtx); double err = ErrMtx.InfNorm(); double infNrm = LaplaceMtx.InfNorm(); Console.WriteLine("Matrix comparison error: " + err + ", matrix norm is: " + infNrm); Assert.Less(err, infNrm * 1e-10, "MsrMatrix2 comparison failed."); #endif stw.Stop(); Console.WriteLine("done {0} sec.", stw.Elapsed.TotalSeconds); //var JB = LapaceIp.GetFDJacobianBuilder(T.Mapping.Fields, null, T.Mapping, edgQrSch, volQrSch); //var JacobiMtx = new BlockMsrMatrix(T.Mapping); //var JacobiAffine = new double[T.Mapping.LocalLength]; //JB.ComputeMatrix(JacobiMtx, JacobiAffine); //double L2ErrAffine = GenericBlas.L2Dist(JacobiAffine, LaplaceAffine); //var ErrMtx2 = LaplaceMtx.CloneAs(); //ErrMtx2.Acc(-1.0, JacobiMtx); //double LinfErrMtx2 = ErrMtx2.InfNorm(); //JacobiMtx.SaveToTextFileSparse("D:\\tmp\\Jac.txt"); //LaplaceMtx.SaveToTextFileSparse("D:\\tmp\\Lap.txt"); //Console.WriteLine("FD Jacobi Mtx: {0:e14}, Affine: {1:e14}", LinfErrMtx2, L2ErrAffine); } }
public void VelocityPredictor(double[] PressureEstimateIn, double[] VelocityEstimateIn, double[] VelocityPrediction, double[] RHSMomentum) { using (new FuncTrace()) { double m_relax_vel = m_SIMPLEOptions.relax_v; //build Matrix var PredictorMX = ConvDiff.CloneAs(); //underrelaxation LHS if (m_relax_vel <= 0.0) { throw new ArithmeticException("Illegal velocity underrelaxation parameter: " + m_relax_vel); } PredictorMX.Acc((1 - m_relax_vel) / m_relax_vel, Aapprox); #if DEBUG PredictorMX.CheckForNanOrInfM(); #endif // build RHS: b1-grad*p (+ oldVelocities/dt) double[] RHS = new double [RHSMomentum.Length]; RHS.AccV(1.0, RHSMomentum); PressureGrad.SpMVpara(-1.0, PressureEstimateIn, 1.0, RHS); //underrelaxation RHS Aapprox.SpMVpara((1 - m_relax_vel) / m_relax_vel, VelocityEstimateIn, 1.0, RHS); // solve using (ISparseSolver solver = m_SIMPLEOptions.ViscousSolver) { //Agglomerator.ClearAgglomerated(RHS, VelocityMapping); //double SolverResidual = PC.SolveDirect(VelocityPrediction.CoordinateVector, RHS, solver, false); //solver.Dispose(); solver.DefineMatrix(PredictorMX); solver.Solve(VelocityPrediction, RHS); } } }
public void Init(MultigridOperator op) { int D = op.Mapping.GridData.SpatialDimension; var M = op.OperatorMatrix; var MgMap = op.Mapping; this.m_mgop = op; if (!M.RowPartitioning.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Row partitioning mismatch."); } if (!M.ColPartition.EqualsPartition(MgMap.Partitioning)) { throw new ArgumentException("Column partitioning mismatch."); } Uidx = MgMap.ProblemMapping.GetSubvectorIndices(true, D.ForLoop(i => i)); Pidx = MgMap.ProblemMapping.GetSubvectorIndices(true, D); int Upart = Uidx.Length; int Ppart = Pidx.Length; ConvDiff = new MsrMatrix(Upart, Upart, 1, 1); pGrad = new MsrMatrix(Upart, Ppart, 1, 1); divVel = new MsrMatrix(Ppart, Upart, 1, 1); var PxP = new MsrMatrix(Ppart, Ppart, 1, 1); M.AccSubMatrixTo(1.0, ConvDiff, Uidx, default(int[]), Uidx, default(int[])); M.AccSubMatrixTo(1.0, pGrad, Uidx, default(int[]), Pidx, default(int[])); M.AccSubMatrixTo(1.0, divVel, Pidx, default(int[]), Uidx, default(int[])); M.AccSubMatrixTo(1.0, PxP, Pidx, default(int[]), Pidx, default(int[])); Mtx = M; int L = M.RowPartitioning.LocalLength; int i0 = Mtx.RowPartitioning.i0; P = new MsrMatrix(Mtx); P.Clear(); // Debugging output //ConvDiff.SaveToTextFileSparse("ConvDiff"); //divVel.SaveToTextFileSparse("divVel"); //pGrad.SaveToTextFileSparse("pGrad"); //PxP.SaveToTextFileSparse("PxP"); velMassMatrix = new MsrMatrix(Upart, Upart, 1, 1); op.MassMatrix.AccSubMatrixTo(1.0, velMassMatrix, Uidx, default(int[]), Uidx, default(int[])); switch (SchurOpt) { case SchurOptions.exact: { // Building complete Schur and Approximate Schur MultidimensionalArray Poisson = MultidimensionalArray.Create(Pidx.Length, Pidx.Length); MultidimensionalArray SchurConvPart = MultidimensionalArray.Create(Pidx.Length, Pidx.Length); MultidimensionalArray Schur = MultidimensionalArray.Create(Pidx.Length, Pidx.Length); using (BatchmodeConnector bmc = new BatchmodeConnector()) { bmc.PutSparseMatrix(ConvDiff, "ConvDiff"); bmc.PutSparseMatrix(velMassMatrix, "MassMatrix"); bmc.PutSparseMatrix(divVel, "divVel"); bmc.PutSparseMatrix(pGrad, "pGrad"); bmc.Cmd("Qdiag = diag(diag(MassMatrix))"); bmc.Cmd("invT= inv(Qdiag)"); bmc.Cmd("Poisson = full(invT)*pGrad"); bmc.Cmd("ConvPart = ConvDiff*Poisson"); bmc.Cmd("ConvPart= full(invT)*ConvPart"); bmc.Cmd("ConvPart= divVel*ConvPart"); bmc.Cmd("Poisson = divVel*Poisson"); bmc.Cmd("ConvDiffInv = inv(full(ConvDiff))"); bmc.Cmd("Schur = divVel*ConvDiffInv"); bmc.Cmd("Schur = Schur*pGrad"); bmc.GetMatrix(Poisson, "Poisson"); bmc.GetMatrix(SchurConvPart, "ConvPart"); bmc.GetMatrix(Schur, "-Schur"); bmc.Execute(false); } PoissonMtx_T = Poisson.ToMsrMatrix(); PoissonMtx_H = Poisson.ToMsrMatrix(); SchurConvMtx = SchurConvPart.ToMsrMatrix(); SchurMtx = Schur.ToMsrMatrix(); SchurMtx.Acc(PxP, 1); ConvDiff.AccSubMatrixTo(1.0, P, default(int[]), Uidx, default(int[]), Uidx); pGrad.AccSubMatrixTo(1.0, P, default(int[]), Uidx, default(int[]), Pidx); SchurMtx.AccSubMatrixTo(1.0, P, default(int[]), Pidx, default(int[]), Pidx); return; } case SchurOptions.decoupledApprox: { // Do assembly for approximate Schur inverse invVelMassMatrix = velMassMatrix.CloneAs(); invVelMassMatrix.Clear(); invVelMassMatrixSqrt = invVelMassMatrix.CloneAs(); for (int i = velMassMatrix.RowPartitioning.i0; i < velMassMatrix.RowPartitioning.iE; i++) { if (ApproxScaling) { invVelMassMatrix.SetDiagonalElement(i, 1 / (velMassMatrix[i, i])); invVelMassMatrixSqrt.SetDiagonalElement(i, 1 / (Math.Sqrt(velMassMatrix[i, i]))); } else { invVelMassMatrix.SetDiagonalElement(i, 1); invVelMassMatrixSqrt.SetDiagonalElement(i, 1); } } //invVelMassMatrix.SaveToTextFileSparse("invVelMassMatrix"); //velMassMatrix.SaveToTextFileSparse("velMassMatrix"); //ConvDiffPoissonMtx = MsrMatrix.Multiply(ConvDiff, pGrad); //ConvDiffPoissonMtx = MsrMatrix.Multiply(divVel, ConvDiffPoissonMtx); // Inverse of mass matrix in Matlab //MultidimensionalArray temp = MultidimensionalArray.Create(Uidx.Length, Uidx.Length); //using (BatchmodeConnector bmc = new BatchmodeConnector()) //{ // bmc.PutSparseMatrix(velMassMatrix, "velMassMatrix"); // bmc.Cmd("invVelMassMatrix = inv(full(velMassMatrix))"); // bmc.GetMatrix(temp, "invVelMassMatrix"); // bmc.Execute(false); //} //invVelMassMatrix = temp.ToMsrMatrix(); //ConvDiffPoissonMtx = MsrMatrix.Multiply(ConvDiffPoissonMtx, PoissonMtx); //ConvDiffPoissonMtx = MsrMatrix.Multiply(PoissonMtx, ConvDiffPoissonMtx); //ConvDiff.AccSubMatrixTo(1.0, P, default(int[]), Uidx, default(int[]), Uidx); //pGrad.AccSubMatrixTo(1.0, P, default(int[]), Uidx, default(int[]), Pidx); //ConvDiffPoissonMtx.AccSubMatrixTo(1.0, P, default(int[]), Pidx, default(int[]), Pidx); //op.MassMatrix.SaveToTextFileSparse("MassMatrix"); //velMassMatrix.SaveToTextFileSparse("velMassMatrix2"); // Possion scaled by inverse of the velocity mass matrix PoissonMtx_T = MsrMatrix.Multiply(invVelMassMatrix, pGrad); PoissonMtx_T = MsrMatrix.Multiply(divVel, PoissonMtx_T); ////PoissonMtx_T.Acc(PxP, 1); // p.379 // Poisson scaled by sqrt of inverse of velocity mass matrix PoissonMtx_H = MsrMatrix.Multiply(invVelMassMatrixSqrt, pGrad); PoissonMtx_H = MsrMatrix.Multiply(divVel, PoissonMtx_H); //PoissonMtx_H.Acc(PxP, 1); // p.379 return; } case SchurOptions.SIMPLE: { var invdiag_ConvDiff = ConvDiff.CloneAs(); invdiag_ConvDiff.Clear(); for (int i = ConvDiff.RowPartitioning.i0; i < ConvDiff.RowPartitioning.iE; i++) { invdiag_ConvDiff[i, i] = 1 / ConvDiff[i, i]; } simpleSchur = MsrMatrix.Multiply(invdiag_ConvDiff, pGrad); simpleSchur = MsrMatrix.Multiply(divVel, simpleSchur); return; } default: throw new NotImplementedException("SchurOption"); } //var ConvDiffInvMtx = ConvDiffInv.ToMsrMatrix(); //// x= inv(P)*b !!!!! To be done with approximate Inverse // P.SpMV(1, B, 0, X); }
protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt) { LsUpdate(phystime); // operator-matrix assemblieren OperatorMatrix = new BlockMsrMatrix(MG_Mapping.ProblemMapping); AltOperatorMatrix = new MsrMatrix(MG_Mapping.ProblemMapping); double[] Affine = new double[OperatorMatrix.RowPartitioning.LocalLength]; MultiphaseCellAgglomerator Agg; Agg = LsTrk.GetAgglomerator(this.LsTrk.SpeciesIdS.ToArray(), m_quadOrder, __AgglomerationTreshold: this.THRESHOLD); XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Op.GetMatrixBuilder(base.LsTrk, MG_Mapping.ProblemMapping, null, MG_Mapping.ProblemMapping); mtxBuilder.time = 0.0; mtxBuilder.ComputeMatrix(OperatorMatrix, Affine); Agg.ManipulateMatrixAndRHS(OperatorMatrix, Affine, MG_Mapping.ProblemMapping, MG_Mapping.ProblemMapping); foreach (var S in this.LsTrk.SpeciesNames) { Console.WriteLine(" Species {0}: no of agglomerated cells: {1}", S, Agg.GetAgglomerator(this.LsTrk.GetSpeciesId(S)).AggInfo.SourceCells.NoOfItemsLocally); } MGOp = new MultigridOperator(XAggB, map, OperatorMatrix, this.massFact.GetMassMatrix(map, false), OpConfig, null); Debug.Assert(MGOp.OperatorMatrix != null); Debug.Assert(MGOp.Mapping != null); someVec = GetRHS(Affine, OperatorMatrix); mtxBuilder.ComputeMatrix(AltOperatorMatrix, Affine); Agg.ManipulateMatrixAndRHS(AltOperatorMatrix, Affine, MG_Mapping.ProblemMapping, MG_Mapping.ProblemMapping); //LsTrk.GetSpeciesName(((XdgAggregationBasis)MGOp.Mapping.AggBasis[0]).UsedSpecies[1]); //LsTrk.GetSpeciesName(((XdgAggregationBasis)MGOp.Mapping.AggBasis[0]).UsedSpecies[0]); int nnz = this.OperatorMatrix.GetTotalNoOfNonZeros(); Console.WriteLine("Number of non-zeros in matrix: " + nnz); int nnz2 = this.AltOperatorMatrix.GetTotalNoOfNonZeros(); Assert.IsTrue(nnz == nnz2, "Number of non-zeros in matrix different for " + OperatorMatrix.GetType() + " and " + AltOperatorMatrix.GetType()); Console.WriteLine("Number of non-zeros in matrix (reference): " + nnz2); MsrMatrix Comp = AltOperatorMatrix.CloneAs(); Comp.Acc(-1.0, OperatorMatrix); double CompErr = Comp.InfNorm(); double Denom = Math.Max(AltOperatorMatrix.InfNorm(), OperatorMatrix.InfNorm()); double CompErrRel = Denom > Math.Sqrt(double.Epsilon) ? CompErr / Denom : CompErr; Console.WriteLine("Comparison: " + CompErrRel); Assert.LessOrEqual(CompErrRel, 1.0e-7, "Huge difference between MsrMatrix and BlockMsrMatrix."); base.TerminationKey = true; return(0.0); }
/// <summary> /// Includes assembly of the matrix. /// </summary> /// <param name="L"></param> protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { using (FuncTrace tr = new FuncTrace()) { // create operator // =============== SpatialOperator LapaceIp; { double D = this.GridData.SpatialDimension; double penalty_base = (T.Basis.Degree + 1) * (T.Basis.Degree + D) / D; double penalty_factor = base.Control.penalty_poisson; BoundaryCondMap <BoundaryType> PoissonBcMap = new BoundaryCondMap <BoundaryType>(this.GridData, this.Control.BoundaryValues, "T"); LapaceIp = new SpatialOperator(1, 1, QuadOrderFunc.SumOfMaxDegrees(), "T", "T"); var flux = new ipFlux(penalty_base * base.Control.penalty_poisson, this.GridData.Cells.cj, PoissonBcMap); LapaceIp.EquationComponents["T"].Add(flux); LapaceIp.Commit(); } // Create Matrices // =============== { // time measurement for matrix assembly Stopwatch stw = new Stopwatch(); stw.Start(); // console Console.WriteLine("creating sparse system for {0} DOF's ...", T.Mapping.Ntotal); // quadrature domain var volQrSch = new CellQuadratureScheme(true, CellMask.GetFullMask(this.GridData)); var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetFullMask(this.GridData)); #if DEBUG // in DEBUG mode, we compare 'MsrMatrix' (old, reference implementation) and 'BlockMsrMatrix' (new standard) var RefLaplaceMtx = new MsrMatrix(T.Mapping); #endif using (new BlockTrace("SipMatrixAssembly", tr)) { LaplaceMtx = new BlockMsrMatrix(T.Mapping); LaplaceAffine = new double[T.Mapping.LocalLength]; LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping, LaplaceMtx, LaplaceAffine, volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch); } #if DEBUG LaplaceAffine.ClearEntries(); LapaceIp.ComputeMatrixEx(T.Mapping, null, T.Mapping, RefLaplaceMtx, LaplaceAffine, volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch); MsrMatrix ErrMtx = RefLaplaceMtx.CloneAs(); ErrMtx.Acc(-1.0, LaplaceMtx); double err = ErrMtx.InfNorm(); double infNrm = LaplaceMtx.InfNorm(); Console.WriteLine("Matrix comparison error: " + err + ", matrix norm is: " + infNrm); Assert.Less(err, infNrm * 1e-10, "MsrMatrix2 comparison failed."); #endif stw.Stop(); Console.WriteLine("done {0} sec.", stw.Elapsed.TotalSeconds); } //double condNo = LaplaceMtx.condest(BatchmodeConnector.Flavor.Octave); //Console.WriteLine("condition number: {0:0.####E-00} ",condNo); } }