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); }