protected override bool MovePointtoTarget(ParticlesofCell TreatedCell, int signKey, MultidimensionalArray Coordinate, List <ParticleCorrectionMask> ParticleMask) { BoundingBox Box = new BoundingBox(SpatialDimension); Grid.iGeomCells.GetCellBoundingBox(TreatedCell.CellIndex, Box); double AdvectionStepLengthINI = Box.Diameter * 1e-2; MultidimensionalArray Phi; MultidimensionalArray Normal; double lambda = 1; bool cellPosSure = true; for (int it = 0; it < max_AddandAttract_Iteration - 1; it++, cellPosSure = false) { Phi = Evaluate(new DGField[] { Interface }, Coordinate, TreatedCell.CellIndex, cellPosSure); //Console.WriteLine("Initial Phi: " + Phi[0, 0]); if (signKey * Phi[0, 0] < Band_max && signKey * Phi[0, 0] > Band_min) { TreatedCell.ItemList[signKey].Add(new SingleLvlSetParticle(Coordinate, AdvectionStepLengthINI)); ParticleCorrectionMask other = new ParticleCorrectionMask(TreatedCell.CellIndex, new int[] { -1, 1 }); int index; if ((index = ParticleMask.FindIndex(other.Compare)) == -1) { ParticleMask.Add(new ParticleCorrectionMask(TreatedCell.CellIndex)); ParticleMask.Last().MovedPoints[signKey]++; } else { ParticleMask[index].MovedPoints[signKey]++; } return(true); } double Phi_goal = CoordGen.NextDouble() * signKey * (Band_max - Band_min) + signKey * Band_min; Normal = EvaluateNormal(Coordinate, TreatedCell.CellIndex, cellPosSure); for (int d = 0; d < SpatialDimension; d++) { Coordinate[0, d] += lambda * (Phi_goal - Phi[0, 0]) * Normal[0, d]; } cellPosSure = false; //PrintParticleSpecs(GlobalPointOut, Normal, TreatedCell.CellIndex, "It_2 " + it + " Plus"); lambda /= 1 + 1 / max_AddandAttract_Iteration; } return(false); }
public void TriangulateLevelSet() { int nbrofVertices = 0; CelltoArrayindex = new Dictionary <int, int>(); CelltoArrayindexEdge = new Dictionary <int, int>(); Points = new List <VerticesofCell>(); Edges = new List <EdgesofCell>(); AllEdges = new List <Edge>(); ActiveFront = new List <FrontVertice>(); PassiveFront = new List <FrontVertice>(); // Seed initial Edge CellMask CutCells = InterfaceTracker.Regions.GetCutCellMask(); int InitialCell = CutCells.ItemEnum.First(); //Console.WriteLine ("InitialCell: " + InitialCell); MultidimensionalArray LocalPointIn = MultidimensionalArray.Create(1, SpatialDimension); MultidimensionalArray GlobalPointOut = MultidimensionalArray.Create(1, SpatialDimension); bool CellPosSure = true; MultidimensionalArray NewPoint; double CurvatureRadius; double CurvatureRadiusNewPoint; SingleVertice InitialVertice; MultidimensionalArray Tangential; do { do { for (int d = 0; d < SpatialDimension; d++) { LocalPointIn [0, d] = (CoordGen.NextDouble() - 0.5) * 2; } Grid.TransformLocal2Global(LocalPointIn, GlobalPointOut, InitialCell); }while (!ProjectOnLevelSetValue(0.0, GlobalPointOut, InitialCell, ref CellPosSure)); //Console.WriteLine("Initial Point: " + GlobalPointOut[0, 0] + " | " + GlobalPointOut[0, 1]); CellPosSure = false; InitialVertice = new SingleVertice(GlobalPointOut, 0); //Console.WriteLine("Initial Point: "+InitialVertice.Coordinates[0,0]+" | "+InitialVertice.Coordinates[0,1]); InitialVertice.Normal = AdjustNormal(InitialVertice.Coordinates, InitialCell, CellPosSure); CurvatureRadius = CalculateRadius(InitialVertice.Coordinates, InitialCell); //Console.WriteLine("Curvature Radius: " + CurvatureRadius); Tangential = MultidimensionalArray.Create(1, SpatialDimension); Tangential [0, 0] = -InitialVertice.Normal [0, 1]; Tangential [0, 1] = InitialVertice.Normal [0, 0]; NewPoint = VectorAddition(1, InitialVertice.Coordinates, CurvatureRadius * EdgeLengthToCurvatureFraction, Tangential); }while (!ProjectOnLevelSetValue(0.0, NewPoint, InitialCell, ref CellPosSure)); CurvatureRadiusNewPoint = CalculateRadius(InitialVertice.Coordinates, InitialCell); NewPoint = VectorAddition(1, InitialVertice.Coordinates, (CurvatureRadius + CurvatureRadiusNewPoint) / 2 * EdgeLengthToCurvatureFraction, Tangential); if (!ProjectOnLevelSetValue(0.0, NewPoint, InitialCell, ref CellPosSure)) { throw new Exception("Failure in Initial Point projection"); } //Console.WriteLine("Second Point: " + NewPoint[0, 0] + " | " + NewPoint[0, 1]); SingleVertice SecondVertice = new SingleVertice(NewPoint, 0); SecondVertice.Normal = AdjustNormal(SecondVertice.Coordinates, InitialCell, false); if (!AddVerticeToMemory(InitialVertice, InitialCell, MinimalDistanceSearch)) { throw new Exception("Initial Vertice must be outside the Grid"); } nbrofVertices++; int CellIndex = FindCellIndexofPoint(SecondVertice.Coordinates); if (!AddVerticeToMemory(SecondVertice, CellIndex, MinimalDistanceSearch)) { throw new Exception("Second Vertice must be outsinde the Grid"); } nbrofVertices++; Edge SeedEdge = new Edge(InitialVertice, SecondVertice); LongestEdge = SeedEdge.GetEdgeLength(); CellIndex = FindCellIndexofPoint(SeedEdge.Center.Coordinates); //Console.WriteLine("Edge Center Index: " + CellIndex); if (!AddEdgeToMemory(SeedEdge, CellIndex)) { throw new Exception("Seed Edge must be outside the Grid"); } ActiveFront.Add(new FrontVertice(SeedEdge, 0, InitialCell)); ActiveFront.Add(new FrontVertice(SeedEdge, 1, InitialCell)); // Continue Triangulation Edge NextEdge; int EdgeCellIndex; //Console.WriteLine("Start Triangulation:" + ActiveFront.Count); while (!ActiveFront.IsNullOrEmpty()) { for (int k = 0; k < ActiveFront.Count; k++) { //Console.WriteLine(); MultidimensionalArray FrontVerticeCoord = ActiveFront[k].Edge.Vertice[ActiveFront[k].VerticeIndex].Coordinates; Edge FrontEdge = ActiveFront[k].Edge; //Console.WriteLine("Front Vertice:" + FrontVerticeCoord[0, 0]+ " | " + FrontVerticeCoord[0, 1]); MultidimensionalArray NextPoint; CellPosSure = false; double multi = 1; MultidimensionalArray ExtensionVector; double CurvatureRadius_0 = CalculateRadius(ActiveFront[k].Edge.Vertice[ActiveFront[k].VerticeIndex].Coordinates, ActiveFront[k].CellIndexGuess); do { ExtensionVector = FrontEdge.EdgeExtensionVector(ActiveFront[k].VerticeIndex); //Console.WriteLine("Extension: " + ExtensionVector[0, 0] + " | " + ExtensionVector[0, 1]); //Console.WriteLine("Origin Edge Length: " + FrontEdge.GetEdgeLength()); double ExtensionVecLen = FrontEdge.GetEdgeLength() * multi; NextPoint = VectorAddition(1, FrontVerticeCoord, ExtensionVecLen, ExtensionVector); //Console.WriteLine("NewPoint: " + NextPoint[0, 0] + " | " + NextPoint[0, 1]); multi /= 2; }while (!ProjectOnLevelSetValue(0.0, NextPoint, ActiveFront[k].CellIndexGuess, ref CellPosSure)); double CurvatureRadius_1 = CalculateRadius(NextPoint, ActiveFront[k].CellIndexGuess); NextPoint = VectorAddition(1, ActiveFront[k].Edge.Vertice[ActiveFront[k].VerticeIndex].Coordinates, (CurvatureRadius_0 + CurvatureRadius_1) * 0.5 * EdgeLengthToCurvatureFraction, ExtensionVector); if (!ProjectOnLevelSetValue(0.0, NextPoint, ActiveFront[k].CellIndexGuess, ref CellPosSure)) { throw new Exception("Failure in NextPoint Attraction while Triangulation"); } //Console.WriteLine("Next Vertice:" + NextPoint[0, 0] + " | " + NextPoint[0, 1]); bool EdgeDiscarded = false; for (int i = 0; i < ActiveFront.Count; i++) { if (i == k) { continue; } double dist = VectorNorm(ComputeVectorbetweenPoints(NextPoint, ActiveFront[i].Edge.Vertice[ActiveFront[i].VerticeIndex].Coordinates)); if (dist < LongestEdge) { //Console.WriteLine(i); double OriginEdgeLen = ActiveFront[i].Edge.GetEdgeLength(); double NeighbourEdgeLen = ActiveFront[k].Edge.GetEdgeLength(); if (dist < OriginEdgeLen * 0.5 || dist < NeighbourEdgeLen * 0.5) { PassiveFront.Add(ActiveFront[k]); ActiveFront.RemoveAt(k--); EdgeDiscarded = true; } } } for (int i = 0; i < PassiveFront.Count && EdgeDiscarded == false; k++) { double dist = VectorNorm(ComputeVectorbetweenPoints(NextPoint, PassiveFront[i].Edge.Vertice[PassiveFront[i].VerticeIndex].Coordinates)); if (dist < LongestEdge) { double OriginEdgeLen = PassiveFront[i].Edge.GetEdgeLength(); double NeighbourEdgeLen = ActiveFront[k].Edge.GetEdgeLength(); if (dist < OriginEdgeLen * 0.5 || dist < NeighbourEdgeLen * 0.5) { PassiveFront.Add(ActiveFront[k]); ActiveFront.RemoveAt(k--); EdgeDiscarded = true; } } } //Console.WriteLine("New Edge accpeted: " + !EdgeDiscarded); if (!EdgeDiscarded) { CellIndex = FindCellIndexofPoint(NextPoint, ActiveFront[k].CellIndexGuess); SingleVertice NextVertice = new SingleVertice(NextPoint, 0); NextVertice.Normal = AdjustNormal(NextVertice.Coordinates, CellIndex, false); if (!AddVerticeToMemory(NextVertice, CellIndex, MinimalDistanceSearch)) { throw new Exception("Next Vertice must be outsinde the Grid"); } nbrofVertices++; NextEdge = new Edge(ActiveFront[k].Edge, ActiveFront[k].VerticeIndex, NextVertice); double EdgeLength = NextEdge.GetEdgeLength(); LongestEdge = (LongestEdge < EdgeLength) ? EdgeLength : LongestEdge; EdgeCellIndex = FindCellIndexofPoint(NextEdge.Center.Coordinates, CellIndex); if (!AddEdgeToMemory(NextEdge, EdgeCellIndex)) { throw new Exception("Next Edge must be outside the Grid"); } FrontVertice NextFrontVertice = new FrontVertice(NextEdge, ActiveFront[k].VerticeIndex, CellIndex); ActiveFront.RemoveAt(k--); ActiveFront.Add(NextFrontVertice); } } } //Close Remaining Gap if (PassiveFront.Count != 2) { throw new Exception("More than two Ends to connect"); } NextEdge = new Edge(PassiveFront[0].Edge, PassiveFront[0].VerticeIndex, PassiveFront[1].Edge, PassiveFront[1].VerticeIndex); EdgeCellIndex = FindCellIndexofPoint(NextEdge.Center.Coordinates, PassiveFront[0].CellIndexGuess); //Console.WriteLine("Center of final Edge: " + NextEdge.Center.Coordinates[0, 0] + " | " + NextEdge.Center.Coordinates[0, 1]); if (!AddEdgeToMemory(NextEdge, EdgeCellIndex)) { throw new Exception("Final Edge must be outside the Grid"); } /* * Console.WriteLine("Last Edge"); * Console.WriteLine(NextEdge.Vertice[0].Coordinates[0, 0] + " | " + NextEdge.Vertice[0].Coordinates[0, 1]); * Console.WriteLine(NextEdge.Vertice[1].Coordinates[0, 0] + " | " + NextEdge.Vertice[1].Coordinates[0, 1]); * * Console.WriteLine("Nbr of Vertices added: " + nbrofVertices); */ }