Ejemplo n.º 1
0
        /// <summary>
        /// Determines the line segments bounding the selected reference
        /// element (cf. <see cref="RefElement"/>) in reference coordinates
        /// </summary>
        /// <returns></returns>
        private LineSegment[] GetReferenceLineSegments()
        {
            Stack <RefElement> simplexHierarchy = new Stack <RefElement>();
            RefElement         currentSimplex   = RefElement;
            int spatialDimension = RefElement.SpatialDimension;

            int n = 0;

            while (currentSimplex.GetType() != lineSimplex.GetType())
            {
                // If n > 2, the edge of the edge of a simplex is not a line.
                // This is hardly likely in 2d/3d.
                if (n > 2)
                {
                    throw new ApplicationException("Something went terribly wrong.");
                }

                simplexHierarchy.Push(currentSimplex);

                currentSimplex = currentSimplex.FaceRefElement;
                n++;
            }

            MultidimensionalArray vertexCoordinates = MultidimensionalArray.Create(2, 1);

            vertexCoordinates[0, 0] = -1.0;
            vertexCoordinates[1, 0] = 1.0;

            while (simplexHierarchy.Count > 0)
            {
                currentSimplex = simplexHierarchy.Pop();

                int noOfVertices = vertexCoordinates.GetLength(0);
                int D            = currentSimplex.SpatialDimension;
                MultidimensionalArray volumeCoordinates = MultidimensionalArray.Create(
                    noOfVertices * currentSimplex.NoOfFaces, currentSimplex.SpatialDimension);

                for (int e = 0; e < currentSimplex.NoOfFaces; e++)
                {
                    MultidimensionalArray coordinates = MultidimensionalArray.Create(noOfVertices, D);
                    currentSimplex.TransformFaceCoordinates(e, vertexCoordinates, coordinates);

                    for (int i = 0; i < noOfVertices; i++)
                    {
                        for (int d = 0; d < D; d++)
                        {
                            volumeCoordinates[e * noOfVertices + i, d] = coordinates[i, d];
                        }
                    }
                }

                vertexCoordinates = volumeCoordinates;
            }

            Debug.Assert(
                vertexCoordinates.GetLength(0) % 2 == 0,
                "Even number of vertices expected");
            int initialNumberOfLineSegments = vertexCoordinates.GetLength(0) / 2;

            List <LineSegment> lineSegments = new List <LineSegment>(initialNumberOfLineSegments);

            for (int i = 0; i < initialNumberOfLineSegments; i++)
            {
                var p0  = vertexCoordinates.GetRow(2 * i + 0);
                int iP0 = this.RefElement.Vertices.FindRow(p0, 1.0e-8);
                var p1  = vertexCoordinates.GetRow(2 * i + 1);
                int iP1 = this.RefElement.Vertices.FindRow(p1, 1.0e-8);

                LineSegment newSegment = new LineSegment(spatialDimension, this.RefElement,
                                                         p0, p1, iP0, iP1,
                                                         RootFindingAlgorithm);

                if (!lineSegments.Contains(newSegment))
                {
                    lineSegments.Add(newSegment);
                    //tracker.Subscribe(newSegment);
                }
            }

            foreach (LineSegment segment in lineSegments)
            {
                LevelSet levelSetField = levelSetData.LevelSet as LevelSet;
                if (levelSetField != null)
                {
                    segment.ProjectBasisPolynomials(levelSetField.Basis);
                }
            }

            return(lineSegments.ToArray());
        }