예제 #1
0
 /// <summary>
 /// Create interpolator based on <paramref name="sourceMesh"/>
 /// </summary>
 public MeshInterpolator2D(MeshData sourceMesh, MeshValueType sourceType)
 {
     _mesh       = sourceMesh;
     _sourceType = sourceType;
     _searcher   = new MeshSearcher(_mesh);
     _searcher.SetupElementSearch();
     Init();
 }
예제 #2
0
 /// <summary>
 /// Initialize the search data structures.
 /// </summary>
 public void InitSearcher()
 {
     if (_searcher == null)
     {
         _searcher = new MeshSearcher(_mesh);
         _searcher.SetupElementSearch();
     }
 }
예제 #3
0
        /// <summary>
        /// Add a target, by specifying its (x,y) coordinate.
        /// </summary>
        public void AddTarget(double x, double y)
        {
            if (_targets == null)
            {
                _targets = new List <InterPData>();
            }
            if (_searcher == null)
            {
                _searcher = new MeshSearcher(_mesh);
                _searcher.SetupElementSearch();
            }

            InterPData interpData = new InterPData();

            // Setting "out-of-bounds" index
            interpData.Element1Index = -1;

            // Find element that includes the (x,y) coordinate
            MeshElement element = _searcher.FindElement(x, y);

            // Check if element has been found, i.e. includes the (x,y) point
            if (element != null)
            {
                bool found = false;
                interpData.Element1Index = element.Index;

                // Check which face the point belongs to, and which "side" of the face
                bool isQuad   = element.IsQuadrilateral();
                int  numFaces = isQuad ? 4 : 3;
                for (int j = 0; j < numFaces; j++)
                {
                    MeshFace elementFace = element.Faces[j];
                    // From the element (x,y), looking towards the face,
                    // figure out wich node is right and which is left.
                    MeshNode rightNode, leftNode;
                    if (elementFace.LeftElement == element)
                    {
                        rightNode = elementFace.FromNode;
                        leftNode  = elementFace.ToNode;
                    }
                    else
                    {
                        rightNode = elementFace.ToNode;
                        leftNode  = elementFace.FromNode;
                    }

                    // Find also the element on the other side of the face
                    double      otherElementX, otherElementY;
                    MeshElement otherElement = elementFace.OtherElement(element);
                    if (otherElement != null)
                    {
                        otherElementX            = otherElement.XCenter;
                        otherElementY            = otherElement.YCenter;
                        interpData.Element2Index = otherElement.Index;
                    }
                    else
                    {
                        // No other element - boundary face, use center of face.
                        otherElementX = 0.5 * (rightNode.X + leftNode.X);
                        otherElementY = 0.5 * (rightNode.Y + leftNode.Y);
                        // Use "itself" as element-2
                        interpData.Element2Index = element.Index;
                    }


                    // Check if point is on the right side of the line between element and other-element
                    if (MeshExtensions.IsPointInsideLines(x, y, element.XCenter, element.YCenter, rightNode.X, rightNode.Y, otherElementX, otherElementY))
                    {
                        (double w1, double w2, double w3) = MeshExtensions.InterpolationWeights(x, y, element.XCenter, element.YCenter, rightNode.X, rightNode.Y, otherElementX, otherElementY);
                        interpData.NodeIndex      = rightNode.Index;
                        interpData.Element1Weight = w1;
                        interpData.NodeWeight     = w2;
                        interpData.Element2Weight = w3;
                        found = true;
                        break;
                    }
                    // Check if point is on the left side of the line between element and other-element
                    if (MeshExtensions.IsPointInsideLines(x, y, element.XCenter, element.YCenter, otherElementX, otherElementY, leftNode.X, leftNode.Y))
                    {
                        (double w1, double w2, double w3) = MeshExtensions.InterpolationWeights(x, y, element.XCenter, element.YCenter, otherElementX, otherElementY, leftNode.X, leftNode.Y);
                        interpData.NodeIndex      = leftNode.Index;
                        interpData.Element1Weight = w1;
                        interpData.Element2Weight = w2;
                        interpData.NodeWeight     = w3;
                        found = true;
                        break;
                    }
                }

                if (!found) // Should never happen, but just in case
                {
                    interpData.Element1Weight = 1;
                    interpData.Element2Weight = 0;
                    interpData.NodeWeight     = 0;
                    interpData.Element2Index  = element.Index;
                    interpData.NodeIndex      = element.Nodes[0].Index;
                }
            }
            _targets.Add(interpData);
        }