Esempio n. 1
0
        /// <summary>
        /// Calculates the number of sub-steps for each sub-grid
        /// </summary>
        protected Clusterer.Clustering CalculateNumberOfLocalTS(Clusterer.Clustering clustering)
        {
            NumberOfLocalTimeSteps.Clear();

            double[] sendHmin = new double[clustering.NumberOfClusters];
            double[] rcvHmin  = new double[clustering.NumberOfClusters];

            MultidimensionalArray cellMetric = clusterer.GetStableTimestepSize(clustering.SubGrid);

            for (int i = 0; i < clustering.NumberOfClusters; i++)
            {
                double   h_min      = double.MaxValue;
                CellMask volumeMask = clustering.Clusters[i].VolumeMask;
                foreach (Chunk c in volumeMask)
                {
                    int JE = c.JE;
                    for (int j = c.i0; j < JE; j++)
                    {
                        h_min = Math.Min(cellMetric[clustering.SubGrid.LocalCellIndex2SubgridIndex[j]], h_min);
                    }
                }
                sendHmin[i] = h_min;
            }

            // MPI to ensure that each processor has the local time step sizes
            unsafe
            {
                fixed(double *pSend = sendHmin, pRcv = rcvHmin)
                {
                    csMPI.Raw.Allreduce((IntPtr)(pSend), (IntPtr)(pRcv), clustering.NumberOfClusters, csMPI.Raw._DATATYPE.DOUBLE, csMPI.Raw._OP.MIN, csMPI.Raw._COMM.WORLD);
                }
            }

            int[] numOfSubSteps = new int[clustering.NumberOfClusters];
            for (int i = 0; i < numOfSubSteps.Length; i++)
            {
                double fraction = rcvHmin[0] / rcvHmin[i];
                // Accounting for roundoff errors
                double eps = 1.0e-2;
                int    subSteps;
                if (fraction > Math.Floor(fraction) + eps)
                {
                    subSteps = (int)Math.Ceiling(fraction);
                }
                else
                {
                    subSteps = (int)Math.Floor(fraction);
                }

                numOfSubSteps[i] = subSteps;
            }

            List <SubGrid> newClusters = new List <SubGrid>();

            for (int i = 0; i < clustering.NumberOfClusters; i++)
            {
                if (i < clustering.NumberOfClusters - 1 && numOfSubSteps[i] == numOfSubSteps[i + 1])
                {
                    // Combine both sub-grids and remove the previous one
                    SubGrid combinedSubGrid = new SubGrid(clustering.Clusters[i].VolumeMask.Union(clustering.Clusters[i + 1].VolumeMask));
                    newClusters.Add(combinedSubGrid);
                    Debug.WriteLine("CalculateNumberOfLocalTS: Clustering leads to sub-grids which are too similar, i.e. they have the same number of local time steps. They are combined.");
                    NumberOfLocalTimeSteps.Add(numOfSubSteps[i]);

                    i++;
                }
                else
                {
                    newClusters.Add(clustering.Clusters[i]);
                    NumberOfLocalTimeSteps.Add(numOfSubSteps[i]);
                }
            }

#if DEBUG
            Console.WriteLine("COMBINING CLUSTERS");
            for (int i = 0; i < newClusters.Count; i++)
            {
                Console.WriteLine("id=" + i + " -> sub-steps=" + NumberOfLocalTimeSteps[i] + " and elements=" + newClusters[i].GlobalNoOfCells);
            }
#endif

            return(new Clusterer.Clustering(newClusters, clustering.SubGrid));
        }