/// <summary> /// Initialize the search data structures. /// </summary> public void InitSearcher() { if (_searcher == null) { _searcher = new MeshSearcher(_mesh); _searcher.SetupElementSearch(); } }
/// <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(); }
/// <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); }
/// <summary> /// Constructor to use if a <see cref="MeshSearcher"/> is already available. /// </summary> public MeshIntersectionCalculator(IMeshData mesh, MeshSearcher searcher) { _mesh = mesh; _searcher = searcher; }