Beispiel #1
0
        /// <summary>
        /// Creates the sub-grids of the clustering
        /// </summary>
        /// <param name="numOfClusters">Number of clusters</param>
        /// <returns>A list of sub-grids</returns>
        public Clustering CreateClustering(int numOfClusters, SubGrid subGrid = null)
        {
            if (subGrid == null)
            {
                subGrid = new SubGrid(CellMask.GetFullMask(gridData));
            }

            // Attention: numOfCells can equal all local cells or only the local cells of a subgrid,
            // e.g., the fluid cells in an IBM simulation
            int numOfCells = subGrid.LocalNoOfCells;

            MultidimensionalArray cellMetric = GetStableTimestepSize(subGrid);
            MultidimensionalArray means      = CreateInitialMeans(cellMetric, numOfClusters);
            Kmeans Kmean = new Kmeans(cellMetric.To1DArray(), numOfClusters, means.To1DArray());

            // The corresponding sub-grid IDs
            int[] subGridCellToClusterMap = Kmean.Cluster();
            int[] noOfCellsPerCluster     = Kmean.ClusterCount;

            unsafe {
                int[] globalCC = new int[numOfClusters];
                // send = means[]
                // receive = globalMeans[]
                fixed(int *pSend = &noOfCellsPerCluster[0], pRcv = &globalCC[0])
                {
                    csMPI.Raw.Allreduce((IntPtr)(pSend), (IntPtr)(pRcv), numOfClusters, csMPI.Raw._DATATYPE.INT, csMPI.Raw._OP.SUM, csMPI.Raw._COMM.WORLD);
                }

                noOfCellsPerCluster = globalCC;
            }

            int counter = numOfClusters;

            for (int i = 0; i < numOfClusters; i++)
            {
                if (noOfCellsPerCluster[i] == 0)
                {
                    System.Console.WriteLine("Sub-grid/Cluster " + (i + 1) + ", with mean value " + Kmean.Means[i] + ", is empty and not used anymore!");
                    counter--;
                }
            }

            // Generating BitArray for all Subgrids, even for those which are empty, i.e ClusterCount == 0
            BitArray[] baMatrix = new BitArray[numOfClusters];
            for (int i = 0; i < numOfClusters; i++)
            {
                //baMatrix[i] = new BitArray(gridData.iLogicalCells.NoOfCells);
                baMatrix[i] = new BitArray(gridData.iLogicalCells.NoOfLocalUpdatedCells);
            }

            // Filling the BitArrays
            for (int i = 0; i < numOfCells; i++)
            {
                baMatrix[subGridCellToClusterMap[i]][subGrid.SubgridIndex2LocalCellIndex[i]] = true;
            }

            // Generating the sub-grids
            List <SubGrid> clusters = new List <SubGrid>(counter);

            for (int i = 0; i < numOfClusters; i++)
            {
                // Generating only the sub-grids which are not empty
                if (noOfCellsPerCluster[i] != 0)
                {
                    BitArray ba = baMatrix[i];
                    clusters.Add(new SubGrid(new CellMask(gridData, ba)));
                }
            }

            return(new Clustering(clusters, subGrid));
        }
Beispiel #2
0
        /// <summary>
        /// Creates the sub-grids of the clustering
        /// </summary>
        /// <param name="numOfClusters">Number of clusters</param>
        /// <returns>A list of sub-grids</returns>
        public Clustering CreateClustering(int numOfClusters, IList <TimeStepConstraint> timeStepConstraints, SubGrid subGrid = null)
        {
            //using (var tr = new ilPSP.Tracing.FuncTrace()) {
            if (subGrid == null)
            {
                subGrid = new SubGrid(CellMask.GetFullMask(gridData));
            }

            // Attention: numOfCells can equal all local cells or only the local cells of a subgrid,
            // e.g., the fluid cells in an IBM simulation
            int numOfCells = subGrid.LocalNoOfCells;

            MultidimensionalArray cellMetric = GetStableTimestepSize(subGrid, timeStepConstraints);
            MultidimensionalArray means      = CreateInitialMeans(cellMetric, numOfClusters);
            Kmeans Kmean = new Kmeans(cellMetric.To1DArray(), numOfClusters, means.To1DArray());

            // The corresponding sub-grid IDs
            int[] subGridCellToClusterMap = Kmean.Cluster();
            int[] noOfCellsPerCluster     = Kmean.ClusterCount;

            unsafe {
                int[] globalCC = new int[numOfClusters];
                // send = means[]
                // receive = globalMeans[]
                fixed(int *pSend = &noOfCellsPerCluster[0], pRcv = &globalCC[0])
                {
                    csMPI.Raw.Allreduce((IntPtr)(pSend), (IntPtr)(pRcv), numOfClusters, csMPI.Raw._DATATYPE.INT, csMPI.Raw._OP.SUM, csMPI.Raw._COMM.WORLD);
                }

                noOfCellsPerCluster = globalCC;
            }

            int counter = numOfClusters;

            for (int i = 0; i < numOfClusters; i++)
            {
                if (noOfCellsPerCluster[i] == 0)
                {
                    if (consoleOutput)
                    {
                        Console.WriteLine("Sub-grid/Cluster " + (i + 1) + ", with mean value " + Kmean.Means[i] + ", is empty and not used anymore!");
                    }
                    counter--;
                }
            }

            // Generating BitArray for all Subgrids, even for those which are empty, i.e ClusterCount == 0
            BitArray[] baMatrix = new BitArray[numOfClusters];
            for (int i = 0; i < numOfClusters; i++)
            {
                //baMatrix[i] = new BitArray(gridData.iLogicalCells.NoOfCells);
                baMatrix[i] = new BitArray(gridData.iLogicalCells.NoOfLocalUpdatedCells);
            }

            // Filling the BitArrays
            for (int i = 0; i < numOfCells; i++)
            {
                baMatrix[subGridCellToClusterMap[i]][subGrid.SubgridIndex2LocalCellIndex[i]] = true;
            }

            // IBM source cells are assigned to the cluster of the corresponding target cells
            // This code is only excuted in IBM simulation runs
            if (this.cellAgglomerator != null)
            {
                // MPI exchange in order to get cellToClusterMap (local + external cells)
                int   JE = gridData.iLogicalCells.Count;
                int   J  = gridData.iLogicalCells.NoOfLocalUpdatedCells;
                int[] cellToClusterMap = new int[JE];

                int   JSub   = subGrid.LocalNoOfCells;
                int[] jSub2j = subGrid.SubgridIndex2LocalCellIndex;
                for (int jsub = 0; jsub < JSub; jsub++)
                {
                    cellToClusterMap[jSub2j[jsub]] = subGridCellToClusterMap[jsub];
                }
                cellToClusterMap.MPIExchange(gridData);

                foreach (AgglomerationPair aggPair in this.cellAgglomerator.AggInfo.AgglomerationPairs)
                {
                    // AgglomerationPairs can contain combinations where jCellSource is on one MPI rank
                    // and the corresponding target cell is on another MPI rank. These duplications have to be eleminated.
                    if (aggPair.jCellSource < J)
                    {
                        // Assign source cell to the cluster of the corresponding target cell
                        int clusterOfTargetCell = cellToClusterMap[aggPair.jCellTarget];
                        baMatrix[clusterOfTargetCell][aggPair.jCellSource] = true;

                        // Delete source cell from other clusters
                        for (int j = 0; j < numOfClusters; j++)
                        {
                            if (clusterOfTargetCell != j)
                            {
                                baMatrix[j][aggPair.jCellSource] = false;
                            }
                        }
                    }
                }
            }

            // Generating the sub-grids
            List <SubGrid> clusters = new List <SubGrid>(counter);

            for (int i = 0; i < numOfClusters; i++)
            {
                // Generating only the sub-grids which are not empty
                if (noOfCellsPerCluster[i] != 0)
                {
                    BitArray ba = baMatrix[i];
                    clusters.Add(new SubGrid(new CellMask(gridData, ba)));
                }
            }

            if (consoleOutput)
            {
                for (int i = 0; i < clusters.Count; i++)
                {
                    Console.WriteLine("CreateClustering:\t id=" + i + " ->\t\telements=" + clusters[i].GlobalNoOfCells);
                }
            }

            return(new Clustering(clusters, subGrid));
        }