/// <summary> /// Subdivides the leaves of thee tree. /// </summary> /// <param name="leavesLevel"> /// <see cref="SubdivideCutLeaves"/>. /// </param> /// <param name="refinedVertexSet"> /// <see cref="SubdivideCutLeaves"/>. /// </param> /// <param name="checkIsCut"> /// If true, leaves will only be subdivided if <see cref="IsCut"/> /// returns true. /// </param> /// <param name="minDistance"> /// See <see cref="IsCut"/>. /// </param> /// <returns> /// True, if at least one node has been subdivided. Otherwise, /// false is returned. /// </returns> private bool SubdivideLeaves(int leavesLevel, NestedVertexSet refinedVertexSet, bool checkIsCut, double minDistance) { bool result = false; if (level < leavesLevel) { if (Children.Count > 0) { foreach (Node child in Children) { result |= child.SubdivideLeaves(leavesLevel, refinedVertexSet, checkIsCut, minDistance); } } } else if (level == leavesLevel) { Debug.Assert(Children.Count == 0, "Can only subdivide leaves"); if (!checkIsCut || (checkIsCut && IsPotentiallyCut(minDistance))) { AffineTrafo[] transformations = owner.refElement.GetSubdivision(); int N = globalVertexIndices.Length; int D = owner.refElement.SpatialDimension; foreach (AffineTrafo elementaryTransformation in transformations) { AffineTrafo combinedTransformation = Transformation * elementaryTransformation; int[] transfomedVertexIndices = new int[N]; for (int i = 0; i < N; i++) { double[] vertex = owner.refElement.Vertices.GetRow(i); vertex = combinedTransformation.Transform(vertex); transfomedVertexIndices[i] = refinedVertexSet.RegisterVertex(vertex); } Children.Add(new Node( owner, this, level + 1, refinedVertexSet, transfomedVertexIndices, combinedTransformation)); result = true; } } else { return(false); } } else { throw new ArgumentException("Given leaves level is higher than the depth of the tree", "leavesLevel"); } return(result); }
/// <summary> /// Initializes the subdivision of the given simplex. Initially, the /// simplex remains undivided. /// </summary> /// <param name="refElement"> /// The simplex to subdivide. /// </param> /// <param name="tracker"> /// The level set tracker. Allows for the check if a simplex ist cut. /// </param> /// <param name="levSetIndex">Index of the level set</param> /// <param name="maxDivisions"> /// The maximum number of subdivisions of the simplex /// </param> public AdaptiveSubdivisionStrategy(RefElement refElement, LevelSetTracker.LevelSetData levelSetData, int maxDivisions) { this.RefElement = refElement; this.maxDivisions = maxDivisions; this.baseVertexSet = new NestedVertexSet(refElement.SpatialDimension); this.LevelSetData = levelSetData; int verticesPerCell = refElement.Vertices.GetLength(0); int[] simplexVertices = new int[verticesPerCell]; for (int i = 0; i < verticesPerCell; i++) { double[] vertex = refElement.Vertices.GetRow(i); simplexVertices[i] = baseVertexSet.RegisterVertex(vertex); } this.subdivisionTree = new SimplexSubdivisionTree( refElement, baseVertexSet, simplexVertices); this.subdivisionTree.SetSavePoint(); }