Esempio n. 1
0
        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);
             */
        }