Ejemplo n.º 1
0
 /// <summary>
 /// Uses <see cref="SubdivisionNode.NullSubdivisionNode"/> to create an
 /// identity transformation for the given simplex. The chunks of
 /// <paramref name="mask"/> are not altered.
 /// </summary>
 /// <param name="mask">
 /// <see cref="ISubdivisionStrategy.GetSubdivisionNodes"/>
 /// </param>
 /// <returns>
 /// <see cref="ISubdivisionStrategy.GetSubdivisionNodes"/>
 /// </returns>
 public IEnumerable <KeyValuePair <Chunk, IEnumerable <SubdivisionNode> > > GetSubdivisionNodes(ExecutionMask mask)
 {
     foreach (Chunk chunk in mask)
     {
         yield return(new KeyValuePair <Chunk, IEnumerable <SubdivisionNode> >(
                          chunk,
                          new SubdivisionNode[] { SubdivisionNode.NullSubdivisionNode(simplex.SpatialDimension) }));
     }
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Uses <see cref="SubdivisionStrategy"/> to construct the subdivision
        /// nodes of the given simplex. Then, each node is supplied with a
        /// standard quadrature rule of the desired order.
        /// </summary>
        /// <param name="mask">
        /// <see cref="CutCellQuadRuleFactory.GetQuadRuleSet"/>
        /// </param>
        /// <param name="order">
        /// <see cref="CutCellQuadRuleFactory.GetQuadRuleSet"/>
        /// </param>
        /// <returns>
        /// A quadrature rule that is <paramref name="order"/>th order accurate
        /// in every node constructed by <see cref="SubdivisionStrategy"/> that
        /// is not cut by the interface.
        /// </returns>
        public IEnumerable <IChunkRulePair <QuadRule> > GetQuadRuleSet(ExecutionMask mask, int order)
        {
            using (new FuncTrace()) {
                QuadRule baseRule = RefElement.GetQuadratureRule(order);

                var result = new List <ChunkRulePair <QuadRule> >();
                List <SubdivisionNode> lastNodeList = null;
                QuadRule lastRule = null;
                foreach (var chunkNodePair in SubdivisionStrategy.GetSubdivisionNodes(mask))
                {
                    List <SubdivisionNode> nodeList = chunkNodePair.Value.ToList();

                    // Make sure consecutive chunks share the same quad rule
                    // instance if quad rules are equal.
                    if (lastNodeList != null && nodeList.SequenceEqual(lastNodeList))
                    {
                        result.Add(new ChunkRulePair <QuadRule>(
                                       chunkNodePair.Key, lastRule));
                        continue;
                    }

                    QuadRule[] quadRules = new QuadRule[nodeList.Count];
                    int        noOfNodes = 0;
                    for (int i = 0; i < nodeList.Count; i++)
                    {
                        QuadRule leafRule = baseRule;
                        if (nodeList[i].IsCut)
                        {
                            leafRule = cutNodeRule ?? baseRule;
                        }

                        quadRules[i] = leafRule;
                        noOfNodes   += leafRule.NoOfNodes;
                    }

                    QuadRule rule   = QuadRule.CreateEmpty(RefElement, noOfNodes, RefElement.SpatialDimension);
                    int      offset = 0;
                    for (int k = 0; k < nodeList.Count; k++)
                    {
                        QuadRule        leaveRule = quadRules[k];
                        SubdivisionNode node      = nodeList[k];
                        double          det       = node.Transformation.Matrix.Determinant();

                        for (int i = 0; i < leaveRule.NoOfNodes; i++)
                        {
                            double[] vertex = node.Transformation.Transform(
                                leaveRule.Nodes.ExtractSubArrayShallow(i, -1).To1DArray());
                            rule.Nodes.SetSubVector(vertex, offset + i, -1);
                            rule.Weights[offset + i] = det * leaveRule.Weights[i];
                        }

                        offset += leaveRule.NoOfNodes;
                    }

                    result.Add(new ChunkRulePair <QuadRule>(
                                   chunkNodePair.Key, rule));

                    lastRule = rule;
                    rule.Nodes.LockForever();
                    lastNodeList = nodeList;
                }

                return(result);
            }
        }