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); } } }
/// <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); } }
void ComputeMatrix() { using (new FuncTrace()) { m_OperatorMatrix.Clear(); m_SpatialOperator.ComputeMatrixEx <MsrMatrix, IList <double> >(m_ColMapping, m_ParameterFields, m_RowMapping, m_OperatorMatrix, null); } }
/// <summary> /// another legacy interface /// </summary> static public void ComputeAffine <V>( this SpatialOperator op, UnsetteledCoordinateMapping DomainMap, IList <DGField> Parameters, UnsetteledCoordinateMapping CodomainMap, V AffineOffset, bool OnlyBoundaryEdges = true, double time = 0.0, EdgeQuadratureScheme edgeQr = null, CellQuadratureScheme volQr = null) where V : IList <double> { var GridDat = CodomainMap.GridDat; if (Parameters != null) { foreach (var prm in Parameters) { if (!object.ReferenceEquals(prm.GridDat, GridDat)) { throw new ArgumentException(string.Format("parameter field {0} is assigned to a different grid.", prm.Identification)); } } } //Using order zero for DomainMap will lead to inconsistent (and possibly insufficient) quadrature order!!! //UnsetteledCoordinateMapping DomainMap; //Basis b = new Basis(GridDat, 0); //Basis[] B = new Basis[this.DomainVar.Count]; //B.SetAll(b); //DomainMap = new UnsetteledCoordinateMapping(B); if (OnlyBoundaryEdges) { if (edgeQr != null) { throw new ArgumentException("If 'OnlyBoundaryEdges == true', 'edgeQr' must be null!", "edgeQr"); } if (volQr != null) { throw new ArgumentException("If 'OnlyBoundaryEdges == true', 'volQr' must be null!", "volQr"); } volQr = new CellQuadratureScheme(true, CellMask.GetEmptyMask(GridDat)); edgeQr = new EdgeQuadratureScheme(true, GridDat.GetBoundaryEdgeMask()); } op.ComputeMatrixEx( DomainMap, Parameters, CodomainMap, default(MsrMatrix), AffineOffset, OnlyAffine: true, time: time, volQuadScheme: volQr, edgeQuadScheme: edgeQr); }
private MsrMatrix PenaltyMatrix(EdgeMask em, Basis LevSetBasis, Basis JumpBasis) { var OpA = new SpatialOperator(1, 0, 1, QuadOrderFunc.Linear(), "Phi", "c1"); OpA.EquationComponents["c1"].Add(new JumpForm()); //OpA.EquationComponents["c1"].Add(new GradientJumpForm() { ATerm = true, BTerm = true }); OpA.EquationComponents["c1"].Add(new GradientJumpForm2()); OpA.Commit(); //var OpB = new SpatialOperator(1, 0, 1, "Phi", "c1"); //Op.EquationComponents["c1"].Add(new JumpForm()); //OpB.EquationComponents["c1"].Add(new GradientJumpForm() { BTerm = true }); //Op.EquationComponents["c1"].Add(new GradientJumpForm2()); //OpB.Commit(); var inp_LevSet_Mapping = new UnsetteledCoordinateMapping(LevSetBasis); var outp_Result_Mapping = new UnsetteledCoordinateMapping(JumpBasis); MsrMatrix MatrixA; MatrixA = new MsrMatrix(outp_Result_Mapping, inp_LevSet_Mapping); double[] AffineA = new double[inp_LevSet_Mapping.LocalLength]; OpA.ComputeMatrixEx(inp_LevSet_Mapping, null, outp_Result_Mapping, MatrixA, AffineA, OnlyAffine: false, edgeQuadScheme: new EdgeQuadratureScheme(true, em), volQuadScheme: new CellQuadratureScheme(true, CellMask.GetEmptyMask(em.GridData))); MatrixA.CheckForNanOrInfM(); //MsrMatrix MatrixB; //MatrixB = new MsrMatrix(outp_Result_Mapping, inp_LevSet_Mapping); //double[] AffineB = new double[inp_LevSet_Mapping.LocalLength]; //OpB.ComputeMatrixEx(inp_LevSet_Mapping, null, outp_Result_Mapping, // MatrixB, AffineB, OnlyAffine: false // );//, // //edgeQrCtx: new EdgeQuadratureScheme(true, em), // //volQrCtx: new CellQuadratureScheme(true, CellMask.GetEmptyMask(em.GridData))); //Debug.Assert(AffineB.L2Norm() == 0); //var Err = MatrixA.Transpose(); //Err.Acc(-1.0, MatrixB); //double errnorm = Err.InfNorm(); //Debug.Assert(errnorm < 1.0e-10); ////Console.WriteLine("Errnorm:" + errnorm); return(MatrixA); }
/// <summary> /// /// </summary> /// <param name="spatialOp"></param> /// <param name="fields"></param> /// <param name="matrix"></param> /// <param name="affineOffset"></param> /// <param name="OnlyAffine"> /// if true, only the <paramref name="affineOffset"/> /// is computed and <paramref name="matrix"/> is null on exit. /// </param> public static void ComputeMatrix(SpatialOperator spatialOp, CoordinateMapping fields, bool OnlyAffine, out MsrMatrix matrix, out double[] affineOffset) { // Check operator and arguments if (!spatialOp.IsCommited) { throw new ArgumentException("operator must be committed first.", "spatialOp"); } if (spatialOp.ContainsNonlinear) { throw new ArgumentException("spatial differential operator cannot contain nonlinear components for implicit euler.", "spatialOp"); } if (!spatialOp.ContainsLinear()) { throw new ArgumentException("spatial differential operator seems to contain no components.", "spatialOp"); } if (spatialOp.DomainVar.Count != spatialOp.CodomainVar.Count) { throw new ArgumentException("spatial differential operator must have the same number of domain and codomain variables.", "spatialOp"); } if (fields.Fields.Count != spatialOp.CodomainVar.Count) { throw new ArgumentException("the number of fields in the coordinate mapping must be equal to the number of domain/codomain variables of the spatial differential operator", "fields"); } // Assemble matrix and affine offset IPartitioning matrixPartition = fields; if (!OnlyAffine) { matrix = new MsrMatrix(matrixPartition); } else { matrix = null; } affineOffset = new double[fields.LocalLength]; spatialOp.ComputeMatrixEx( fields, null, fields, matrix, affineOffset, OnlyAffine); }
/// <summary> /// ctor. /// </summary> public LinearSolver(ISparseSolver solver, SpatialOperator spatialOp, CoordinateMapping UnknownsMap) { // verify input // ------------ if (!spatialOp.IsCommited) { throw new ArgumentException("operator must be committed first.", "spatialOp"); } if (spatialOp.ContainsNonlinear) { throw new ArgumentException("spatial differential operator cannot contain nonlinear components for linear solver.", "spatialOp"); } if (!spatialOp.ContainsLinear()) { throw new ArgumentException("spatial differential operator seems to contain no components.", "spatialOp"); } if (spatialOp.DomainVar.Count != spatialOp.CodomainVar.Count) { throw new ArgumentException("spatial differential operator must have the same number of domain and codomain variables.", "spatialOp"); } if (UnknownsMap.Fields.Count != spatialOp.CodomainVar.Count) { throw new ArgumentException("the number of fields in the coordinate mapping must be equal to the number of domain/codomain variables of the spatial differential operator", "fields"); } m_Mapping = UnknownsMap; m_Solver = solver; // matrix assembly // --------------- MsrMatrix eM; { eM = new MsrMatrix(m_Mapping); m_AffineOffset = new double[m_Mapping.LocalLength]; spatialOp.ComputeMatrixEx(m_Mapping, null, m_Mapping, eM, m_AffineOffset); } ConstructorCommon(eM); }
public ExplicitConvection(Context context, string variablename, SubGrid subgrid, int basisdegree , SubgridCoordinateMapping v) { m_Context = context; name = variablename; convectionop = new SpatialOperator(1, 3, 1, name, "u", "v", "w"); convectionop.EquationComponents["Density"].Add(new SurfaceConvectionUpwinding(new string[] { "u", "v", "w" }, subgrid, new string[] { name }, 0)); convectionop.Commit(); CreepingFlowFactory fact = new CreepingFlowFactory(m_Context, basisdegree); fact.CreateFlowFields(out creepingFlow); Partition part = new Partition(v.NUpdate); double[] affine = new double[v.NUpdate]; MsrMatrix opmatr = new MsrMatrix(part, v.MaxTotalNoOfCoordinatesPerCell * (int)m_Context.GridDat.GlobalNoOfCells); convectionop.ComputeMatrixEx(m_Context, v, new Field[] { creepingFlow[0], creepingFlow[1], creepingFlow[2] }, v, opmatr, affine, false, subgrid); v.SetupSubmatrix(affine, opmatr, out SubgridAffine, out SubgridOperatorMatr); }
/// <summary> /// checks whether the linear and nonlinear implementation of operator evaluation are mathematically equal /// </summary> void LinearNonlinComparisonTest() { int L = this.bnd.CoordinateVector.Count(); // need to assure to use the same quadrature oder on both evaluation variants var volQrSch = (new CellQuadratureScheme(false, CellMask.GetFullMask(this.GridData, MaskType.Geometrical))) .AddFixedOrderRules(this.GridData, this.PolynomialDegree * 3); var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetFullMask(this.GridData, MaskType.Geometrical)) .AddFixedOrderRules(this.GridData, this.PolynomialDegree * 3); //var volQrSch = new CellQuadratureScheme(true, CellMask.GetEmptyMask(this.GridData)); //var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetEmptyMask(this.GridData)); //var edgQrSch = new EdgeQuadratureScheme(true, this.GridData.BoundaryEdges) // .AddFixedOrderRules(this.GridData, this.PolynomialDegree * 3); //var edgQrSch = new EdgeQuadratureScheme(true, this.GridData.BoundaryEdges.Complement()) // .AddFixedOrderRules(this.GridData, this.PolynomialDegree * 3); for (int run = 0; run < 1; run++) { // setup a random test vector Random rnd = new Random(); var TestArgument = this.bnd.CloneAs().CoordinateVector; for (int i = 0; i < L; i++) { TestArgument[i] = rnd.NextDouble(); } Stopwatch lin = new Stopwatch(); Stopwatch nol = new Stopwatch(); // linear evaluation CoordinateVector LinResult = this.ViscU_linear.CoordinateVector; LinResult.Clear(); lin.Start(); { var map = this.U.Mapping; var tempOperatorMtx = new MsrMatrix(map, map); var tempAffine = new double[L]; Operator.ComputeMatrixEx(map, new DGField[] { this.mu }, map, tempOperatorMtx, tempAffine, volQuadScheme: volQrSch, edgeQuadScheme: edgQrSch); tempOperatorMtx.SpMVpara(1.0, TestArgument, 0.0, LinResult); LinResult.AccV(1.0, tempAffine); } lin.Stop(); // nonliner evaluation CoordinateVector NolResult = this.ViscU_nonlinear.CoordinateVector; NolResult.Clear(); nol.Start(); { var evaluator = Operator.GetEvaluatorEx(TestArgument.Mapping, new DGField[] { this.mu }, this.Residual.Mapping, volQrCtx: volQrSch, edgeQrCtx: edgQrSch); evaluator.Evaluate(1.0, 0.0, NolResult); } nol.Stop(); double L2Dist = GenericBlas.L2DistPow2(LinResult, NolResult).MPISum().Sqrt(); Console.WriteLine("L2 dist of linear/Nonlinear evaluation comparison: {0}", L2Dist); LinResult.Acc(-1.0, NolResult); foreach (SinglePhaseField DGfield in LinResult.Mapping.Fields) { for (int p = 0; p <= DGfield.Basis.Degree; p++) { double L2err_p = DGfield.L2NormPerMode(p); Console.WriteLine(" ERR{2} {1} \t{0}", L2err_p, DGfield.Identification, p); } } Console.WriteLine("Time linear {0}, time nonlinear: {1}", lin.Elapsed, nol.Elapsed); Assert.LessOrEqual(L2Dist, 1.0e-4, "L2 distance between linear and nonlinear evaluation of the same flux."); } }
protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L) { using (FuncTrace tr = new FuncTrace()) { this.BcMap = new IncompressibleBoundaryCondMap(this.GridData, grid.GetBoundaryConfig(), PhysicsMode.Incompressible); // assemble system, create matrix // ------------------------------ int D = GridData.SpatialDimension; //double penalty_base = ((double)((U[0].Basis.Degree + 1) * (U[0].Basis.Degree + D))) / ((double)D); double penalty_base = 1.0; double penalty_factor = 1.2; // equation assembly // ----------------- string[] CodNames = D.ForLoop(i => "C" + i); Operator = new SpatialOperator(VariableNames.VelocityVector(D), new string[] { VariableNames.ViscosityMolecular }, CodNames, QuadOrderFunc.Linear()); for (int d = 0; d < D; d++) { if ((this.whichTerms & Terms.T1) != 0) { var flx1 = new swipViscosity_Term1(penalty_base * penalty_factor, d, D, BcMap, ViscosityOption.VariableViscosity); flx1.g_Diri_Override = this.solution.U; flx1.g_Neu_Override = this.solution.dU; Operator.EquationComponents[CodNames[d]].Add(flx1); } if ((this.whichTerms & Terms.T2) != 0) { var flx2 = new swipViscosity_Term2(penalty_base * penalty_factor, d, D, BcMap, ViscosityOption.VariableViscosity); flx2.g_Diri_Override = this.solution.U; flx2.g_Neu_Override = this.solution.dU; Operator.EquationComponents[CodNames[d]].Add(flx2); } if ((this.whichTerms & Terms.T3) != 0) { var flx3 = new swipViscosity_Term3(penalty_base * penalty_factor, d, D, BcMap, ViscosityOption.VariableViscosity); flx3.g_Diri_Override = this.solution.U; flx3.g_Neu_Override = this.solution.dU; Operator.EquationComponents[CodNames[d]].Add(flx3); } } // */ Operator.Commit(); var map = this.U.Mapping; OperatorMtx = new MsrMatrix(map, map); Operator.ComputeMatrixEx(map, new DGField[] { this.mu }, map, OperatorMtx, this.bnd.CoordinateVector, volQuadScheme: null, edgeQuadScheme: null); // test for matrix symmetry // ======================== if (base.MPISize == 1) { double MatrixAssymmetry = OperatorMtx.SymmetryDeviation(); Console.WriteLine("Matrix asymmetry: " + MatrixAssymmetry); Assert.LessOrEqual(Math.Abs(MatrixAssymmetry), 1.0e-10); } } }
// Local Variables for Iteration // <summary> // Counter for Iteration Steps // </summary> //double OldResidual = double.MaxValue; //int divergencecounter = 0; ///// <summary> ///// Checks for Reaching Max. Number of Iterations and Divergence of Algorithm ///// </summary> ///// <param name="Residual">Change Rate of the Algorithm</param> ///// <returns>Reaching Max Iterations, Aborts when diverged</returns> //public bool CheckAbortCriteria(double Residual, int IterationCounter) { // if (Residual <= ConvergenceCriterion) { // Console.WriteLine("EllipticReInit converged after {0} Iterations ", IterationCounter); // return true; // } // if (Residual >= OldResidual) divergencecounter++; // else divergencecounter = 0; // if (IterationCounter >= MaxIteration) { // Console.WriteLine("Elliptic Reinit Max Iterations Reached"); // return true; // }; // if (divergencecounter > MaxIteration / 2) { // Console.WriteLine("Elliptic Reinit diverged - Aborting"); // throw new ApplicationException(); // } // OldResidual = Residual; // IterationCounter++; // return false; //} //bool PreviouslyOnSubgrid = false; /// <summary> /// Updates the Operator Matrix after level-set motion /// </summary> /// <param name="Restriction"> /// The subgrid, on which the ReInit is performed /// </param> /// <param name="IncludingInterface"> /// !! Not yet functional !! /// True, if the subgrid contains the interface, this causes all external edges of the subgrid to be treated as boundaries /// False, for the rest of the domain, thus the flux to the adjacent cells wil be evaluated /// </param> public void UpdateOperators(SubGrid Restriction = null, bool IncludingInterface = true) { if (!IncludingInterface) { throw new NotImplementedException("Untested, not yet functional!"); } using (new FuncTrace()) { //using (var slv = new ilPSP.LinSolvers.MUMPS.MUMPSSolver()) { //using (var slv = new ilPSP.LinSolvers.PARDISO.PARDISOSolver()) { //using (var slv = new ilPSP.LinSolvers.HYPRE.GMRES()) { if (Control.Upwinding) { OldPhi.Clear(); OldPhi.Acc(1.0, Phi); //Calculate LevelSetGradient.Clear(); LevelSetGradient.Gradient(1.0, Phi, Restriction?.VolumeMask); //LevelSetGradient.Gradient(1.0, Phi); //LevelSetGradient.GradientByFlux(1.0, Phi); MeanLevelSetGradient.Clear(); MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient, Restriction?.VolumeMask); //MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient); } if (slv != null) { slv.Dispose(); } slv = Control.solverFactory(); OpMatrix_interface.Clear(); OpAffine_interface.Clear(); // Build the Quadrature-Scheme for the interface operator // Note: The HMF-Quadrature over a surface is formally a volume quadrature, since it uses the volume quadrature nodes. //XSpatialOperatorExtensions.ComputeMatrixEx(Operator_interface, ////Operator_interface.ComputeMatrixEx( // LevelSetTracker, // Phi.Mapping, // null, // Phi.Mapping, // OpMatrix_interface, // OpAffine_interface, // false, // 0, // false, // subGrid:Restriction, // whichSpc: LevelSetTracker.GetSpeciesId("A") // ); XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Operator_interface.GetMatrixBuilder(LevelSetTracker, Phi.Mapping, null, Phi.Mapping); MultiphaseCellAgglomerator dummy = LevelSetTracker.GetAgglomerator(LevelSetTracker.SpeciesIdS.ToArray(), Phi.Basis.Degree * 2 + 2, 0.0); //mtxBuilder.SpeciesOperatorCoefficients[LevelSetTracker.GetSpeciesId("A")].CellLengthScales = dummy.CellLengthScales[LevelSetTracker.GetSpeciesId("A")]; mtxBuilder.CellLengthScales.Add(LevelSetTracker.GetSpeciesId("A"), dummy.CellLengthScales[LevelSetTracker.GetSpeciesId("A")]); mtxBuilder.time = 0; mtxBuilder.MPITtransceive = false; mtxBuilder.ComputeMatrix(OpMatrix_interface, OpAffine_interface); // Regenerate OpMatrix for subgrid -> adjacent cells must be trated as boundary if (Restriction != null) { OpMatrix_bulk.Clear(); OpAffine_bulk.Clear(); //Operator_bulk.ComputeMatrix( // Phi.Mapping, // parameterFields, // Phi.Mapping, // OpMatrix_bulk, OpAffine_bulk, // OnlyAffine: false, sgrd: Restriction); EdgeQuadratureScheme edgescheme; //if (Control.Upwinding) { // edgescheme = new EdgeQuadratureScheme(true, IncludingInterface ? Restriction.AllEdgesMask : null); //} //else { edgescheme = new EdgeQuadratureScheme(true, IncludingInterface ? Restriction.InnerEdgesMask : null); //} Operator_bulk.ComputeMatrixEx(Phi.Mapping, parameterFields, Phi.Mapping, OpMatrix_bulk, OpAffine_bulk, false, 0, edgeQuadScheme: edgescheme, volQuadScheme: new CellQuadratureScheme(true, IncludingInterface ? Restriction.VolumeMask : null) ); //PreviouslyOnSubgrid = true; } // recalculate full Matrix //else if (PreviouslyOnSubgrid) { else { OpMatrix_bulk.Clear(); OpAffine_bulk.Clear(); Operator_bulk.ComputeMatrixEx(Phi.Mapping, parameterFields, Phi.Mapping, OpMatrix_bulk, OpAffine_bulk, false, 0 ); //PreviouslyOnSubgrid = false; } /// Compose the Matrix /// This is symmetric due to the symmetry of the SIP and the penalty term OpMatrix.Clear(); OpMatrix.Acc(1.0, OpMatrix_bulk); OpMatrix.Acc(1.0, OpMatrix_interface); OpMatrix.AssumeSymmetric = !Control.Upwinding; //OpMatrix.AssumeSymmetric = false; /// Compose the RHS of the above operators. (-> Boundary Conditions) /// This does NOT include the Nonlinear RHS, which will be added later OpAffine.Clear(); OpAffine.AccV(1.0, OpAffine_bulk); OpAffine.AccV(1.0, OpAffine_interface); #if Debug ilPSP.Connectors.Matlab.BatchmodeConnector matlabConnector; matlabConnector = new BatchmodeConnector(); #endif if (Restriction != null) { SubVecIdx = Phi.Mapping.GetSubvectorIndices(Restriction, true, new int[] { 0 }); int L = SubVecIdx.Length; SubMatrix = new MsrMatrix(L); SubRHS = new double[L]; SubSolution = new double[L]; OpMatrix.AccSubMatrixTo(1.0, SubMatrix, SubVecIdx, default(int[]), SubVecIdx, default(int[])); slv.DefineMatrix(SubMatrix); #if Debug Console.WriteLine("ConditionNumber of ReInit-Matrix is " + SubMatrix.condest().ToString("E")); #endif } else { slv.DefineMatrix(OpMatrix); #if Debug Console.WriteLine("ConditionNumber of ReInit-Matrix is " + OpMatrix.condest().ToString("E")); #endif } } }
/// <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(); // Stats: { int BlkSize = T.Mapping.MaxTotalNoOfCoordinatesPerCell; int NoOfMtxBlocks = 0; foreach (int[] Neigs in this.GridData.iLogicalCells.CellNeighbours) { NoOfMtxBlocks++; // diagonal block NoOfMtxBlocks += Neigs.Length; // off-diagonal block } NoOfMtxBlocks = NoOfMtxBlocks.MPISum(); int MtxBlockSize = BlkSize * BlkSize; int MtxSize = MtxBlockSize * NoOfMtxBlocks; double MtxStorage = MtxSize * (8.0 + 4.0) / (1024 * 1024); // 12 bytes (double+int) per entry Console.WriteLine(" System size: {0}", T.Mapping.TotalLength); Console.WriteLine(" No of blocks: {0}", T.Mapping.TotalNoOfBlocks); Console.WriteLine(" No of blocks in matrix: {0}", NoOfMtxBlocks); Console.WriteLine(" DG coordinates per cell: {0}", BlkSize); Console.WriteLine(" Non-zeros per matrix block: {0}", MtxBlockSize); Console.WriteLine(" Total non-zeros in matrix: {0}", MtxSize); Console.WriteLine(" Approx. matrix storage (MB): {0}", MtxStorage); base.QueryHandler.ValueQuery("MtxBlkSz", MtxBlockSize, true); base.QueryHandler.ValueQuery("NNZMtx", MtxSize, true); base.QueryHandler.ValueQuery("NNZblk", NoOfMtxBlocks, true); base.QueryHandler.ValueQuery("MtxMB", MtxStorage, true); } 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)); 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); } stw.Stop(); //Print process information Console.WriteLine("done {0} sec.", stw.Elapsed.TotalSeconds); LaplaceMtx.GetMemoryInfo(out long AllocatedMem, out long UsedMem); Console.WriteLine(" Used matrix storage (MB): {0}", UsedMem / (1024.0 * 1024)); Console.WriteLine(" Alloc. matrix storage (MB): {0}", AllocatedMem / (1024.0 * 1024)); } }
/// <summary> /// Create Spatial Operators and build the corresponding Matrices /// </summary> public void ComputeMatrices(IList <DGField> InterfaceParams, bool nearfield) { OpMatrix = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping); OpAffine = new double[OpMatrix.RowPartitioning.LocalLength]; OpMatrix_bulk = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping); OpAffine_bulk = new double[OpMatrix.RowPartitioning.LocalLength]; OpMatrix_interface = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping); OpAffine_interface = new double[OpMatrix.RowPartitioning.LocalLength]; //LevelSetTracker.GetLevelSetGradients(0,); // bulk part of the matrix //Operator_bulk.ComputeMatrix( // Extension.Mapping, // LevelSetGradient.ToArray(), // Extension.Mapping, // OpMatrix_bulk, OpAffine_bulk, // OnlyAffine: false, sgrd: null); switch (Control.FluxVariant) { case FluxVariant.GradientBased: // Flux Direction based on Mean Level Set Gradient BulkParams = new List <DGField> { }; // Hack, to make ArrayTools.Cat produce a List of DGFields // second Hack: Does only work, when InterfaceParams is according to a single component flux, // else, we will have to change the boundary edge flux BulkParams = ArrayTools.Cat(BulkParams, LevelSetGradient.ToArray(), Phi, MeanLevelSetGradient.ToArray(), InterfaceParams.ToArray()); MeanLevelSetGradient.Clear(); MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient); break; case FluxVariant.ValueBased: // Flux Direction Based on Cell-Averaged Level-Set Value BulkParams = ArrayTools.Cat(LevelSetGradient.ToArray(), Phi, MeanLevelSet); MeanLevelSet.Clear(); MeanLevelSet.AccLaidBack(1.0, Phi); break; case FluxVariant.SWIP: BulkParams = LevelSetGradient.ToArray(); break; default: throw new Exception(); } // Build Operator Operator_bulk.ComputeMatrixEx(Extension.Mapping, BulkParams, Extension.Mapping, OpMatrix_bulk, OpAffine_bulk, OnlyAffine: false, time: 0.0, edgeQuadScheme: new EdgeQuadratureScheme(true, nearfield ? LevelSetTracker.Regions.GetNearFieldSubgrid(1).InnerEdgesMask : null), volQuadScheme: new CellQuadratureScheme(true, nearfield ? LevelSetTracker.Regions.GetNearFieldSubgrid(1).VolumeMask : null) ); Operator_interface.ComputeMatrixEx( LevelSetTracker, Extension.Mapping, InterfaceParams, Extension.Mapping, OpMatrix_interface, OpAffine_interface, OnlyAffine: false, time: 0, MPIParameterExchange: false, whichSpc: LevelSetTracker.GetSpeciesId("A") ); #if DEBUG OpMatrix_bulk.CheckForNanOrInfM(); OpAffine_bulk.CheckForNanOrInfV(); OpMatrix_interface.CheckForNanOrInfM(); OpAffine_interface.CheckForNanOrInfV(); #endif //Only for Debugging purposes //OpMatrix.SaveToTextFileSparse("C:\\tmp\\EllipticReInit.txt"); Debug.Assert(OpMatrix_interface.GetDiagVector().L2Norm() > 0, "L2-Norm of Diagonal of InterfaceOperator is 0"); Debug.Assert(OpMatrix_bulk.GetDiagVector().L2Norm() > 0, "L2-Norm of Diagonal of BulkOperator is 0"); #if DEBUG //Console.WriteLine( "L2-Norm of Diagonal of InterfaceOperator is {0}", OpMatrix_interface.GetDiagVector().L2Norm() ); #endif OpMatrix.Clear(); OpMatrix.Acc(1.0, OpMatrix_bulk); OpMatrix.Acc(1.0, OpMatrix_interface); //Console.WriteLine("Op-Matrix Symmetry-Deviation: {0}", OpMatrix.SymmetryDeviation()); OpMatrix.AssumeSymmetric = false; OpAffine.Clear(); OpAffine.AccV(1.0, OpAffine_bulk); OpAffine.AccV(1.0, OpAffine_interface); #if DEBUG //Console.WriteLine("Condition Number of Extension Operator {0}", OpMatrix.condest()); #endif }
/// <summary> /// Create Spatial Operators and build the corresponding Matrices /// </summary> public void ComputeMatrices(IList <DGField> InterfaceParams, bool nearfield) { OpMatrix = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping); OpAffine = new double[OpMatrix.RowPartitioning.LocalLength]; OpMatrix_bulk = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping); OpAffine_bulk = new double[OpMatrix.RowPartitioning.LocalLength]; OpMatrix_interface = new MsrMatrix(this.Extension.Mapping, this.Extension.Mapping); OpAffine_interface = new double[OpMatrix.RowPartitioning.LocalLength]; //LevelSetTracker.GetLevelSetGradients(0,); // bulk part of the matrix //Operator_bulk.ComputeMatrix( // Extension.Mapping, // LevelSetGradient.ToArray(), // Extension.Mapping, // OpMatrix_bulk, OpAffine_bulk, // OnlyAffine: false, sgrd: null); switch (Control.FluxVariant) { case FluxVariant.GradientBased: // Flux Direction based on Mean Level Set Gradient BulkParams = new List <DGField> { }; // Hack, to make ArrayTools.Cat produce a List of DGFields // second Hack: Does only work, when InterfaceParams is according to a single component flux, // else, we will have to change the boundary edge flux BulkParams = ArrayTools.Cat(BulkParams, LevelSetGradient.ToArray(), Phi, MeanLevelSetGradient.ToArray(), InterfaceParams.ToArray()); MeanLevelSetGradient.Clear(); MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient); break; case FluxVariant.ValueBased: // Flux Direction Based on Cell-Averaged Level-Set Value BulkParams = ArrayTools.Cat(LevelSetGradient.ToArray(), Phi, MeanLevelSet); MeanLevelSet.Clear(); MeanLevelSet.AccLaidBack(1.0, Phi); break; case FluxVariant.SWIP: BulkParams = LevelSetGradient.ToArray(); break; default: throw new Exception(); } // Build Operator Operator_bulk.ComputeMatrixEx(Extension.Mapping, BulkParams, Extension.Mapping, OpMatrix_bulk, OpAffine_bulk, OnlyAffine: false, time: 0.0, edgeQuadScheme: new EdgeQuadratureScheme(true, nearfield ? LevelSetTracker.Regions.GetNearFieldSubgrid(1).InnerEdgesMask : null), volQuadScheme: new CellQuadratureScheme(true, nearfield ? LevelSetTracker.Regions.GetNearFieldSubgrid(1).VolumeMask : null) ); //Operator_interface.ComputeMatrixEx( // LevelSetTracker, // Extension.Mapping, // InterfaceParams, // Extension.Mapping, // OpMatrix_interface, // OpAffine_interface, // OnlyAffine: false, // time: 0, // MPIParameterExchange: false, // whichSpc: LevelSetTracker.GetSpeciesId("A") // ); Operator_interface.OperatorCoefficientsProvider = delegate(LevelSetTracker lstrk, SpeciesId spc, int quadOrder, int TrackerHistoryIdx, double time) { var r = new CoefficientSet() { }; //throw new NotImplementedException("todo"); return(r); }; XSpatialOperatorMk2.XEvaluatorLinear mtxBuilder = Operator_interface.GetMatrixBuilder(LevelSetTracker, Extension.Mapping, InterfaceParams, Extension.Mapping); MultiphaseCellAgglomerator dummy = LevelSetTracker.GetAgglomerator(LevelSetTracker.SpeciesIdS.ToArray(), 2 * Extension.Basis.Degree + 2, 0.0); mtxBuilder.CellLengthScales.Add(LevelSetTracker.GetSpeciesId("A"), dummy.CellLengthScales[LevelSetTracker.GetSpeciesId("A")]); mtxBuilder.time = 0; mtxBuilder.MPITtransceive = false; mtxBuilder.ComputeMatrix(OpMatrix_interface, OpAffine_interface); #if DEBUG OpMatrix_bulk.CheckForNanOrInfM(); OpAffine_bulk.CheckForNanOrInfV(); OpMatrix_interface.CheckForNanOrInfM(); OpAffine_interface.CheckForNanOrInfV(); #endif //Only for Debugging purposes Debug.Assert(OpMatrix_interface.GetDiagVector().L2Norm() > 0, "L2-Norm of Diagonal of InterfaceOperator is 0"); Debug.Assert(OpMatrix_bulk.GetDiagVector().L2Norm() > 0, "L2-Norm of Diagonal of BulkOperator is 0"); #if DEBUG //Console.WriteLine( "L2-Norm of Diagonal of InterfaceOperator is {0}", OpMatrix_interface.GetDiagVector().L2Norm() ); #endif OpMatrix.Clear(); OpMatrix.Acc(1.0, OpMatrix_bulk); OpMatrix.Acc(1.0, OpMatrix_interface); //Console.WriteLine("Op-Matrix Symmetry-Deviation: {0}", OpMatrix.SymmetryDeviation()); OpMatrix.AssumeSymmetric = false; OpAffine.Clear(); OpAffine.AccV(1.0, OpAffine_bulk); OpAffine.AccV(1.0, OpAffine_interface); #if DEBUG //Console.WriteLine("Condition Number of Extension Operator {0}", OpMatrix.condest()); #endif }
/// <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); } }