private void FindBodyAndTipNodesAndElements(HashSet <XNode> bodyNodes, HashSet <XNode> tipNodes, List <XContinuumElement2D> tipElements) { foreach (var element in Mesh.Elements) { element.EnrichmentItems.Clear(); ElementEnrichmentType type = CharacterizeElementEnrichment(element); if (type == ElementEnrichmentType.Tip) { tipElements.Add(element); foreach (var node in element.Nodes) { tipNodes.Add(node); } element.EnrichmentItems.Add(CrackTipEnrichments); } else if (type == ElementEnrichmentType.Heaviside) { foreach (var node in element.Nodes) { bodyNodes.Add(node); } // Cut elements next to tip elements, they will be enriched with both Heaviside and tip functions. If all // nodes were enriched with tip functions, the element would not be enriched with Heaviside, but then it // would be a tip element and not fall under this case. element.EnrichmentItems.Add(CrackBodyEnrichment); } } foreach (var node in tipNodes) { bodyNodes.Remove(node); // tip element's nodes are not enriched with Heaviside } ReportTipElements(tipElements); }
// Warning: TipElements must first be cleared in this iteration private void FindBodyAndTipNodesAndElements(HashSet <XNode> bodyNodes, HashSet <XNode> tipNodes) { var bothElements = new HashSet <XContinuumElement2D>(); foreach (var element in Mesh.Elements) { element.EnrichmentItems.Clear(); ElementEnrichmentType type = CharacterizeElementEnrichment(element); if (type == ElementEnrichmentType.Tip) { tipElements.Add(element); foreach (var node in element.Nodes) { tipNodes.Add(node); } element.EnrichmentItems.Add(CrackTipEnrichments); } else if (type == ElementEnrichmentType.Heaviside) { foreach (var node in element.Nodes) { bodyNodes.Add(node); } element.EnrichmentItems.Add(CrackBodyEnrichment); } else if (type == ElementEnrichmentType.Both) { tipElements.Add(element); bothElements.Add(element); foreach (var node in element.Nodes) { tipNodes.Add(node); bodyNodes.Add(node); } element.EnrichmentItems.Add(CrackTipEnrichments); element.EnrichmentItems.Add(CrackBodyEnrichment); } } // After all Heaviside nodes are aggregated remove the nodes of tip elements foreach (var element in tipElements) { foreach (var node in element.Nodes) { bodyNodes.Remove(node); } } foreach (var element in bothElements) // Re-adding these nodes afterwards is safer { foreach (var node in element.Nodes) { bodyNodes.Add(node); } } ReportTipElements(tipElements); }
public SortedSet <CartesianPoint> FindTriangleVertices(XContinuumElement2D element) { var triangleVertices = new SortedSet <CartesianPoint>(element.Nodes, pointComparer); int nodesCount = element.Nodes.Count; ElementEnrichmentType type = CharacterizeElementEnrichment(element); if (type != ElementEnrichmentType.Standard) { // Find the intersections between element edges and the crack. TODO: See Serafeim's Msc Thesis for a correct procedure. for (int i = 0; i < nodesCount; ++i) { XNode node1 = element.Nodes[i]; XNode node2 = element.Nodes[(i + 1) % nodesCount]; double levelSet1 = levelSetsBody[node1]; double levelSet2 = levelSetsBody[node2]; if (levelSet1 * levelSet2 < 0.0) { // The intersection point between these nodes can be found using the linear interpolation, see // Sukumar 2001 double k = -levelSet1 / (levelSet2 - levelSet1); double x = node1.X + k * (node2.X - node1.X); double y = node1.Y + k * (node2.Y - node1.Y); // TODO: For the tip element one intersection point is on the crack extension and does not // need to be added. It is not wrong though. triangleVertices.Add(new CartesianPoint(x, y)); } else if (levelSet1 == 0.0) { triangleVertices.Add(node1); // TODO: perhaps some tolerance is needed. } else if (levelSet2 == 0.0) { triangleVertices.Add(node2); } } if (type == ElementEnrichmentType.Tip) { triangleVertices.Add(crackTip); } } return(triangleVertices); }