public EdgeMask GetEdges4RefElement(RefElement Kref) { if (m_Edges4RefElement == null) { m_Edges4RefElement = new EdgeMask[this.EdgeRefElements.Length]; } int iKref = this.EdgeRefElements.IndexOf(Kref, (a, b) => object.ReferenceEquals(a, b)); if (m_Edges4RefElement[iKref] == null) { EdgeMask parrEdg = m_Owner.ParentGrid.iGeomEdges.GetEdges4RefElement(Kref); EdgeMask thisAll = EdgeMask.GetFullMask(this.m_Owner, MaskType.Geometrical); if (parrEdg.MaskType != MaskType.Geometrical) { throw new ApplicationException("expecting a geometrical mask"); } if (thisAll.MaskType != MaskType.Geometrical) { throw new ApplicationException("expecting a geometrical mask"); } BitArray parrBitmask = parrEdg.GetBitMask().CloneAs(); BitArray thisBitMask = thisAll.GetBitMask(); Debug.Assert(parrBitmask.Length == thisBitMask.Length); BitArray intersect = parrBitmask.And(thisBitMask); Debug.Assert(object.ReferenceEquals(intersect, parrBitmask)); m_Edges4RefElement[iKref] = new EdgeMask(m_Owner, intersect, MaskType.Geometrical); } return(m_Edges4RefElement[iKref]); }
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); } }
public static void Plot(IGrid grid) { EdgeMask boundaryEdges = EdgeMask.GetFullMask(grid.iGridData, MaskType.Logical); boundaryEdges.SaveToTextFile( "edges.txt", false, (double[] CoordGlobal, int LogicalItemIndex, int GeomItemIndex) => grid.iGridData.iGeomEdges.EdgeTags[GeomItemIndex]); Tecplot plt1 = new Tecplot(grid.iGridData, true, false, 0); Basis b = new Basis(grid.iGridData, 0); SinglePhaseField field = new SinglePhaseField(b, "u"); plt1.PlotFields("grid", 0, field); }
/// <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."); } }
/// <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)); } }
public IEnumerable <IChunkRulePair <QuadRule> > GetQuadRuleSet(ExecutionMask mask, int order) { if (mask == null) { mask = EdgeMask.GetFullMask(tracker.Ctx.GridDat); } if (mask is EdgeMask == false) { throw new Exception(); } QuadRule baseRule = lineSimplex.GetQuadratureRule(order); int D = tracker.Ctx.Grid.GridSimplex.SpatialDimension; var result = new List <ChunkRulePair <QuadRule> >(mask.NoOfItemsLocally); foreach (Chunk chunk in mask) { for (int i = 0; i < chunk.Len; i++) { List <double[]> nodes = new List <double[]>(); List <double> weights = new List <double>(); int[] noOfNodesPerEdge = new int[referenceLineSegments.Length]; int edge = i + chunk.i0; // Always choose 'left' edge int cell = tracker.Ctx.GridDat.Edges[edge, 0]; int localEdge = tracker.Ctx.GridDat.EdgeIndices[edge, 0]; LineSegment referenceSegment = referenceLineSegments[localEdge]; double[] roots = referenceSegment.GetRoots(tracker.LevelSets[levSetIndex], cell); LineSegment[] subSegments = referenceSegment.Split(roots); for (int k = 0; k < subSegments.Length; k++) { for (int m = 0; m < baseRule.NoOfNodes; m++) { // Base rule _always_ is a line rule, thus Nodes[*, _0_] double[] point = subSegments[k].GetPointOnSegment(baseRule.Nodes[m, 0]); uint lh = tracker.Ctx.NSC.LockNodeSetFamily( tracker.Ctx.NSC.CreateContainer( MultidimensionalArray.CreateWrapper(point, 1, D), -1.0)); MultidimensionalArray levelSetValue = tracker.GetLevSetValues(levSetIndex, 0, cell, 1); tracker.Ctx.NSC.UnlockNodeSetFamily(lh); // Only positive volume if (levelSetValue[0, 0] <= 0.0) { continue; } weights.Add(baseRule.Weights[m] * subSegments[k].Length / referenceSegment.Length); nodes.Add(point); } } if (weights.Count == 0) { continue; } MultidimensionalArray localNodes = MultidimensionalArray.Create(nodes.Count, D); for (int j = 0; j < nodes.Count; j++) { for (int d = 0; d < D; d++) { localNodes[j, d] = nodes[j][d]; } } MultidimensionalArray localEdgeNodes = MultidimensionalArray.Create(nodes.Count, 1); tracker.Ctx.Grid.GridSimplex.VolumeToEdgeCoordinates(localEdge, localNodes, localEdgeNodes); QuadRule subdividedRule = new QuadRule() { OrderOfPrecision = order, Weights = MultidimensionalArray.Create(weights.Count), Nodes = localEdgeNodes.CloneAs() }; subdividedRule.Weights.SetV(weights, -1); result.Add(new ChunkRulePair <QuadRule>( Chunk.GetSingleElementChunk(edge), subdividedRule)); } } return(result); }
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 // ------------------------------ var volQrSch = new CellQuadratureScheme(true, CellMask.GetFullMask(this.GridData)); var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetFullMask(this.GridData)); //var volQrSch = new CellQuadratureScheme(true, CellMask.GetEmptyMask(this.GridData)); //var edgQrSch = new EdgeQuadratureScheme(true, EdgeMask.GetEmptyMask(this.GridData)); //var edgQrSch = new EdgeQuadratureScheme(true, this.GridDat.BoundaryEdges); //var edgQrSch = new EdgeQuadratureScheme(true, this.GridDat.BoundaryEdges.Complement()); int D = GridData.SpatialDimension; double penalty_base = ((double)((U[0].Basis.Degree + 1) * (U[0].Basis.Degree + D))) / ((double)D); 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, this.GridData.Cells.cj, d, D, BcMap, this.viscOption, 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, this.GridData.Cells.cj, d, D, BcMap, this.viscOption, 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, this.GridData.Cells.cj, d, D, BcMap, this.viscOption, 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: volQrSch, edgeQuadScheme: edgQrSch); // 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); } } }
/// <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); } }