Example #1
0
        /// <summary>
        /// Finds the valid flow tiles to be put in a position given by row and column indices.
        /// The constraints are that edge fluxes should match and that the field needs to be divergence free.
        /// </summary>
        /// <param name="rowNumber">Row index in grid</param>
        /// <param name="colNumber">Column index in grid</param>
        /// <returns>List of valid tiles to put in that position</returns>
        /// <exception cref="ArgumentException">
        /// If there already is a tile in the given position this exception is thrown.
        /// </exception>
        private List <FlowTile> ValidTiles(int rowNumber, int colNumber)
        {
            if (tileGrid.HasTile(rowNumber, colNumber))
            {
                throw new ArgumentException("Tile already exists on that position");
            }

            int[][] validFluxRanges = new int[4][];
            for (int i = 0; i < 4; i++)
            {
                validFluxRanges[i] = new int[2];
            }

            /*
             * int[] validTopFluxRange = new int[2];
             * int[] validBottomFluxRange = new int[2];
             * int[] validLeftFluxRange = new int[2];
             * int[] validRightFluxRange = new int[2];
             */

            //Finds the restrictions on corner velocities
            Vector2?[] restrictions = velocityRestrictions(rowNumber, colNumber);
            //Finds all valid combinations of the allowed corner velocities.
            List <CornerVelocities> allowedCornerVelocities = cornerVelocityCombinations(restrictions);

            for (int i = 0; i < 4; i++)
            {
                LPSolve.SetEdgeToSolve(rowNumber, colNumber, (LPSolve.Direction)i, gridDimension, false);
                validFluxRanges[i][0] = LPSolve.SolveModel();
                LPSolve.SetEdgeToSolve(rowNumber, colNumber, (LPSolve.Direction)i, gridDimension, true);
                validFluxRanges[i][1] = LPSolve.SolveModel();
            }

            List <FlowTile> currentValidTiles = new List <FlowTile>();

            //Create all possible FlowTiles given the bounds on flows. This set still needs to be filtered
            for (int i = validFluxRanges[0][0]; i <= validFluxRanges[0][1]; i++)
            {
                for (int j = validFluxRanges[1][0]; j <= validFluxRanges[1][1]; j++)
                {
                    for (int k = validFluxRanges[2][0]; k <= validFluxRanges[2][1]; k++)
                    {
                        for (int l = validFluxRanges[3][0]; l <= validFluxRanges[3][1]; l++)
                        {
                            foreach (CornerVelocities cornerVelocities in allowedCornerVelocities)
                            {
                                Flux flux = new Flux();
                                flux.TopEdge    = i;
                                flux.RightEdge  = j;
                                flux.BottomEdge = k;
                                flux.LeftEdge   = l;

                                currentValidTiles.Add(new FlowTile(innerTileGridDimension, flux, cornerVelocities));
                            }
                        }
                    }
                }
            }
            List <FlowTile> validTiles =
                LPSolve.FilterValidTiles(currentValidTiles, rowNumber, colNumber, gridDimension);

            Console.WriteLine("final number of tiles: " + validTiles.Count);
            foreach (FlowTile tile in validTiles)
            {
                Console.WriteLine("Top: " + tile.Flux.TopEdge);
                Console.WriteLine("Right: " + tile.Flux.RightEdge);
                Console.WriteLine("Bottom: " + tile.Flux.BottomEdge);
                Console.WriteLine("Left: " + tile.Flux.LeftEdge + "\n");
            }


            return(validTiles);
        }