/// <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)); }