/// <summary>
        /// Computes refinement and coarsening lists
        /// (inputs for <see cref="GridData.Adapt(IEnumerable{int}, IEnumerable{int[]}, out GridCorrelation)"/>),
        /// based on the max refinement level provided by the calling solver. This method is fully parallized.
        /// </summary>
        /// <param name="currentGrid">
        /// </param>
        /// <param name="cellsToRefine">
        /// Output, local indices of cells which should be refined.
        /// </param>
        /// <param name="cellsToCoarsen">
        /// Output, clusters of cells (identified by local cell indices) which can be combined into coarser cells.
        /// </param>
        /// <param name="CellsMaxRefineLevel">
        /// All cells, sorted in CellMask with their desired maximum level of refinement. Due to its nature as a list it is possible to define multiple different mask.
        /// ATTENTION: If to many CellMasks are defined the refinement algorithm might be slow.
        /// </param>
        /// <returns>
        /// True if any refinement or coarsening of the current grid should be performed; otherwise false.
        /// </returns>
        public static bool ComputeGridChange(GridData currentGrid, CellMask CellsNotOKToCoarsen, List <Tuple <int, BitArray> > CellsMaxRefineLevel, out List <int> cellsToRefine, out List <int[]> cellsToCoarsen)
        {
            int[][] globalCellNeigbourship = GetGlobalCellNeigbourship(currentGrid);

            int[] CellsWithMaxRefineLevel = GetAllCellsWithMaxRefineLevel(currentGrid, CellsMaxRefineLevel);
            int[] levelIndicator          = GetGlobalLevelIndicator(currentGrid, CellsWithMaxRefineLevel, globalCellNeigbourship);
            int[] globalDesiredLevel      = GetGlobalDesiredLevel(currentGrid, levelIndicator, globalCellNeigbourship);
            cellsToRefine = GetCellsToRefine(currentGrid, globalDesiredLevel);

            BitArray oK2Coarsen = GetCellsOk2Coarsen(currentGrid, CellsNotOKToCoarsen, globalDesiredLevel, globalCellNeigbourship);

            int[][] coarseningClusters = FindCoarseningClusters(oK2Coarsen, currentGrid);
            cellsToCoarsen = GetCoarseningCells(currentGrid, coarseningClusters);

            bool anyChangeInGrid = (cellsToRefine.Count() == 0 && cellsToCoarsen.Count() == 0) ? false : true;

            bool[] exchangeGridChange = anyChangeInGrid.MPIGatherO(0);
            exchangeGridChange = exchangeGridChange.MPIBroadcast(0);
            for (int m = 0; m < exchangeGridChange.Length; m++)
            {
                if (exchangeGridChange[m])
                {
                    anyChangeInGrid = true;
                }
            }
            return(anyChangeInGrid);
        }
        /// <summary>
        /// Gets all cells to refine and writes them to a int-list.
        /// </summary>
        /// <param name="currentGrid">
        /// </param>
        /// <param name="cellsNotOK2Coarsen">
        /// A CellMask of all cells which should never be coarsend, e.g. all cut cells.
        /// </param>
        /// <param name="globalDesiredLevel">
        /// The desired level of all global cells.
        /// </param>
        /// <param name="globalCellNeigbourship">
        /// Jaggerd int-array where the first index refers to the current cell and the second one to the neighbour cells.
        /// </param>
        private static BitArray GetCellsOk2Coarsen(GridData currentGrid, CellMask cellsNotOK2Coarsen, int[] globalDesiredLevel, int[][] globalCellNeigbourship)
        {
            int          oldJ             = currentGrid.Cells.NoOfLocalUpdatedCells;
            BitArray     oK2Coarsen       = new BitArray(oldJ);
            Partitioning cellPartitioning = currentGrid.CellPartitioning;
            int          i0     = cellPartitioning.i0;
            int          myRank = currentGrid.MpiRank;

            int[][] cellNeighbours = currentGrid.Cells.CellNeighbours;

            for (int globalCellIndex = i0; globalCellIndex < i0 + oldJ; globalCellIndex++)
            {
                int localCellIndex = globalCellIndex - i0;
                int ActualLevel_j  = currentGrid.Cells.GetCell(localCellIndex).RefinementLevel;

                if (ActualLevel_j > globalDesiredLevel[globalCellIndex] &&
                    globalDesiredLevel[globalCellIndex] >= globalCellNeigbourship[globalCellIndex].Select(neighbourIndex => globalDesiredLevel[neighbourIndex]).Max() - 1)
                {
                    oK2Coarsen[localCellIndex] = true;
                }
            }

            if (cellsNotOK2Coarsen != null)
            {
                foreach (int j in cellsNotOK2Coarsen.ItemEnum)
                {
                    oK2Coarsen[j] = false;
                }
            }

            return(oK2Coarsen);
        }
Esempio n. 3
0
 /// <summary>
 /// ctor
 /// </summary>
 /// <param name="volMask">
 /// volume mask for those cells which should be contained in the subgrid
 /// </param>
 public SubGrid(CellMask volMask)
 {
     MPICollectiveWatchDog.Watch();
     if (volMask.MaskType != MaskType.Logical)
     {
         throw new ArgumentException();
     }
     this.m_VolumeMask = volMask;
     m_GridData        = volMask.GridData;
 }
        /// <summary>
        /// Computes refinement and coarsening lists
        /// (inputs for <see cref="GridData.Adapt(IEnumerable{int}, IEnumerable{int[]}, out GridCorrelation)"/>),
        /// based on a refinement indicator. If the calculation should work parallel it is recommend to use <see cref="ComputeGridChange(GridData, List{Tuple{int, CellMask}}, out List{int}, out List{int[]})"/>.
        /// </summary>
        /// <param name="currentGrid">
        /// Current grid.
        /// </param>
        /// <param name="levelIndicator">
        /// Mapping from (local cell index, current refinement level) to desired refinement level for the respective cell,
        /// see <see cref="Cell.RefinementLevel"/>.
        /// </param>
        /// <param name="cellsToRefine">
        /// Output, local indices of cells which should be refined.
        /// </param>
        /// <param name="cellsToCoarsen">
        /// Output, clusters of cells (identified by local cell indices) which can be combined into coarser cells.
        /// </param>
        /// <param name="CutCells">
        /// If not null, a mask of cells in which coarsening is forbidden (usually cut-cells);
        /// </param>
        /// <returns>
        /// True if any refinement or coarsening of the current grid should be performed; otherwise false.
        /// </returns>
        public static bool ComputeGridChange(GridData currentGrid, CellMask CutCells, Func <int, int, int> levelIndicator, out List <int> cellsToRefine, out List <int[]> cellsToCoarsen)
        {
            int[][] globalCellNeigbourship = GetGlobalCellNeigbourship(currentGrid);
            int[]   globalDesiredLevel     = GetGlobalDesiredLevel(currentGrid, levelIndicator, globalCellNeigbourship);
            cellsToRefine = GetCellsToRefine(currentGrid, globalDesiredLevel);

            BitArray oK2Coarsen = GetCellsOk2Coarsen(currentGrid, CutCells, globalDesiredLevel, globalCellNeigbourship);

            int[][] coarseningClusters = FindCoarseningClusters(oK2Coarsen, currentGrid);
            cellsToCoarsen = GetCoarseningCells(currentGrid, coarseningClusters);

            bool anyChangeInGrid = (cellsToRefine.Count() == 0 && cellsToCoarsen.Count() == 0) ? false : true;

            return(anyChangeInGrid);
        }
Esempio n. 5
0
        /// <summary>
        /// Computes <see cref="SubgridIndex2LocalCellIndex"/>
        /// </summary>
        /// <returns></returns>
        private int[] ComputeSubgridIndex2LocalCellIndex()
        {
            MPICollectiveWatchDog.Watch();
            CellMask msk = m_VolumeMask;

            int[] subgridIndex2LocalCellIndex = new int[msk.NoOfItemsLocally_WithExternal];
            int   jj = 0;

            foreach (Chunk c in msk.GetEnumerableWithExternal())
            {
                for (int k = 0; k < c.Len; k++)
                {
                    subgridIndex2LocalCellIndex[jj] = c.i0 + k;
                    jj++;
                }
            }
            return(subgridIndex2LocalCellIndex);
        }
 /// <summary>
 /// Constructor for the grid refinement controller, defines input cells
 /// </summary>
 /// <param name="currentGrid">
 /// Current grid.
 /// </param>
 /// <param name="cutCells">
 /// Cut cells will have always the max refinement level. Null is a valid input if no level-set is used.
 /// </param>
 /// <param name="cellsNotOK2Coarsen">
 /// Cells which are not allowed to be coarsend. It is not necessary to include cut cells here, as they are handled by the cutCells CellMask.
 /// </param>
 public GridRefinementController(GridData currentGrid, CellMask cutCells, CellMask cellsNotOK2Coarsen = null)
 {
     CurrentGrid                 = currentGrid;
     CellPartitioning            = CurrentGrid.CellPartitioning;
     LocalNumberOfCells          = CurrentGrid.Cells.NoOfLocalUpdatedCells;
     GlobalIndexOfFirstLocalCell = CellPartitioning.i0;
     GlobalNumberOfCells         = CellPartitioning.TotalLength;
     CutCells = cutCells;
     if (CutCells == null)
     {
         CutCells = CellMask.GetEmptyMask(CurrentGrid);
     }
     if (cellsNotOK2Coarsen == null)
     {
         cellsNotOK2Coarsen = CellMask.GetEmptyMask(CurrentGrid);
     }
     CellsNotOK2Coarsen = cellsNotOK2Coarsen.Union(CutCells).GetBitMask();
 }
Esempio n. 7
0
        /// <summary>
        /// Converts this
        /// from a geometrical (<see cref="IGridData.iGeomCells"/>) mask
        /// to a  logical (<see cref="IGridData.iLogicalCells"/>) mask.
        /// </summary>
        /// <returns></returns>
        public CellMask ToLogicalMask()
        {
            if (base.MaskType != MaskType.Geometrical)
            {
                throw new NotSupportedException();
            }

            if (base.GridData is Grid.Classic.GridData || GridData.iGeomCells.GeomCell2LogicalCell == null)
            {
                // logical and geometrical cells are identical - return a clone of this mask
                return(new CellMask(base.GridData, base.Sequence, MaskType.Logical));
            }
            else
            {
                int[] jG2jL = GridData.iGeomCells.GeomCell2LogicalCell;

                int      Jl = GridData.iLogicalCells.NoOfLocalUpdatedCells;
                BitArray ba = new BitArray(Jl);


                foreach (Chunk c in this)             // loop over chunks of logical cells...
                {
                    for (int jG = 0; jG < c.JE; jG++) // loop over cells in chunk...
                    {
                        int jL = jG2jL[jG];

                        ba[jL] = true;
                    }
                }

                var cmL = new CellMask(base.GridData, ba, MaskType.Logical);
#if DEBUG
                // convert new logical mask back to geometrical and see if both masks are equal
                BitArray shouldBeEqual = (cmL.ToGeometicalMask()).GetBitMask();
                BitArray thisMask      = this.GetBitMask();
                Debug.Assert(shouldBeEqual.Length == thisMask.Length);
                for (int j = 0; j < shouldBeEqual.Length; j++)
                {
                    Debug.Assert(shouldBeEqual[j] == thisMask[j]);
                }
#endif
                return(cmL);
            }
        }
Esempio n. 8
0
        /// <summary>
        /// see <see cref="DGField.Acc(double,DGField,Grid.CellMask)"/>;
        /// </summary>
        public override void Acc(double mult, DGField a, Grid.CellMask cm)
        {
            using (new FuncTrace()) {
                if (!a.Basis.Equals(this.Basis))
                {
                    throw new ArgumentException("Basis of 'a' must be equal to basis of this field", "a");
                }

                SinglePhaseField _a = a as SinglePhaseField;

                if (cm == null && _a != null &&
                    this.m_Mda_Coordinates.IsContinious && _a.m_Mda_Coordinates.IsContinious)
                {
                    // optimized branch
                    // ++++++++++++++++
                    double[] storThis = this.m_Mda_Coordinates.Storage;
                    double[] strOther = _a.m_Mda_Coordinates.Storage;

                    int i0This = this.m_Mda_Coordinates.Index(0, 0);
                    int i0Othr = _a.m_Mda_Coordinates.Index(0, 0);
                    int N      = this.Mapping.LocalLength;
                    int inc    = 1;

                    unsafe
                    {
                        fixed(double *pStorThis = storThis, pStrOther = strOther)
                        {
                            BLAS.F77_BLAS.DAXPY(ref N, ref mult, pStrOther, ref inc, pStorThis, ref inc);
                        }
                    }
                }
                else
                {
                    // default branch
                    // ++++++++++++++

                    base.Acc(mult, a, cm);
                }
            }
        }
Esempio n. 9
0
        /// <summary>
        /// a cell is in the returned cell mask if
        /// it is a neighbor cell of this edge mask and if it is also neighbor of <paramref name="X"/>
        /// </summary>
        public CellMask GetAdjacentCellsCond(CellMask X)
        {
            var gridData = (Grid.Classic.GridData)(base.GridData);

            int J = gridData.Cells.NoOfLocalUpdatedCells;

            int[,] AllEdges = gridData.Edges.CellIndices;
            BitArray mask  = new BitArray(J);
            BitArray Xmask = X.GetBitMaskWithExternal();

            foreach (var ch in this)
            {
                int L = ch.i0 + ch.Len;
                for (int l = ch.i0; l < L; l++)
                {
                    int cellIn = AllEdges[l, 0];
                    int cellOt = AllEdges[l, 1];

                    bool Out = (cellOt > 0 && Xmask[cellOt]);
                    bool In_ = Xmask[cellIn];
                    if (!(Out || In_))
                    {
                        continue;
                    }


                    if (cellIn < J)
                    {
                        mask[cellIn] = true;
                    }
                    if (cellOt >= 0 && cellOt < J)
                    {
                        mask[cellOt] = true;
                    }
                }
            }

            return(new CellMask(gridData, mask, MaskType.Logical));
        }
Esempio n. 10
0
        /// <summary>
        /// Computes refinement and coarsening lists
        /// (inputs for <see cref="GridData.Adapt(IEnumerable{int}, IEnumerable{int[]}, out GridCorrelation)"/>),
        /// based on a refinement indicator.
        /// </summary>
        /// <param name="CurrentGrid">
        /// Current grid.
        /// </param>
        /// <param name="LevelIndicator">
        /// Mapping from (local cell index, current refinement level) to desired refinement level for the respective cell,
        /// see <see cref="Cell.RefinementLevel"/>.
        /// </param>
        /// <param name="CellsToRefineList">
        /// Output, local indices of cells which should be refined.
        /// </param>
        /// <param name="Coarsening">
        /// Output, clusters of cells (identified by local cell indices) which can be combined into coarser cells.
        /// </param>
        /// <param name="CutCells">
        /// If not null, a mask of cells in which coarsening is forbidden (usually cut-cells);
        /// </param>
        /// <returns>
        /// True if any refinement or coarsening of the current grid should be performed; otherwise false.
        /// </returns>
        public static bool ComputeGridChange(GridData CurrentGrid, CellMask CutCells, Func <int, int, int> LevelIndicator, out List <int> CellsToRefineList, out List <int[]> Coarsening)
        {
            int oldJ = CurrentGrid.Cells.NoOfLocalUpdatedCells;

            bool NoRefinement = true;

            int[] DesiredLevel = new int[oldJ];
            for (int j = 0; j < oldJ; j++)
            {
                int CurrentLevel_j = CurrentGrid.Cells.GetCell(j).RefinementLevel;
                int DesiredLevel_j = LevelIndicator(j, CurrentLevel_j);

                if (DesiredLevel[j] < DesiredLevel_j)
                {
                    DesiredLevel[j] = DesiredLevel_j;
                    NoRefinement    = false;
                    RefineNeighboursRecursive(CurrentGrid, DesiredLevel, j, DesiredLevel_j - 1);
                }
            }

            BitArray Ok2Coarsen = new BitArray(oldJ);

            for (int j = 0; j < oldJ; j++)
            {
                int ActualLevel_j  = CurrentGrid.Cells.GetCell(j).RefinementLevel;
                int DesiredLevel_j = DesiredLevel[j];

                int[][] CellNeighbours = CurrentGrid.Cells.CellNeighbours;

                if (ActualLevel_j > DesiredLevel_j && DesiredLevel_j >= CellNeighbours[j].Select(cn => DesiredLevel[cn]).Max() - 1)
                {
                    Ok2Coarsen[j] = true;
                }
            }
            if (CutCells != null)
            {
                foreach (int j in CutCells.ItemEnum)
                {
                    Ok2Coarsen[j] = false;
                }
            }


            int[][] CClusters = FindCoarseningClusters(Ok2Coarsen, CurrentGrid);

            Coarsening = new List <int[]>();
            int NoOfCellsToCoarsen = 0;

            for (int j = 0; j < oldJ; j++)
            {
                if (CClusters[j] != null)
                {
                    NoOfCellsToCoarsen++;

                    Debug.Assert(CClusters[j].Contains(j));
                    if (j == CClusters[j].Min())
                    {
                        Coarsening.Add(CClusters[j]);
                    }
                }
            }

            CellsToRefineList = new List <int>();
            if ((!NoRefinement) || (Coarsening.Count > 0))
            {
                for (int j = 0; j < oldJ; j++)
                {
                    int ActualLevel_j  = CurrentGrid.Cells.GetCell(j).RefinementLevel;
                    int DesiredLevel_j = DesiredLevel[j];

                    if (ActualLevel_j < DesiredLevel_j)
                    {
                        CellsToRefineList.Add(j);
                    }
                }
            }

            // If any cells which should refined are members of CutCells
            if (CellsToRefineList.Count == 0 && Coarsening.Count == 0)
            {
                NoRefinement = true;
            }


            return(!NoRefinement);
        }
Esempio n. 11
0
        /// <summary>
        /// Find the cell which contains some point <paramref name="pt"/>;
        /// If <paramref name="pt"/> is not within any cell, the cell with its
        /// center nearest to <paramref name="pt"/> is returned and in this
        /// case, <paramref name="IsInside"/> is false.
        /// </summary>
        /// <param name="pt"></param>
        /// <param name="GlobalId">
        /// the Global ID of the found cell;
        /// </param>
        /// <param name="GlobalIndex">
        /// the Global index of the found cell;
        /// </param>
        /// <param name="IsInside">
        /// true, if <paramref name="pt"/> is within the cell identified by
        /// <paramref name="GlobalId"/>;
        /// otherwise, false;
        /// </param>
        /// <param name="OnThisProcess">
        /// If true, the cell <paramref name="GlobalId"/> is located on the current MPI process.
        /// </param>
        /// <param name="CM">
        /// optional cell mask to restrict the search region
        /// </param>
        /// <remarks>
        /// This operation is relatively costly, as it needs to perform a sweep
        /// over all cells, it should not be used for performance-critical
        /// tasks.<br/>
        /// This operation is MPI-collective, the output-values are equal on
        /// all MPI-processors.
        /// </remarks>
        static public void LocatePoint(this IGridData gdat, double[] pt, out long GlobalId, out long GlobalIndex, out bool IsInside, out bool OnThisProcess, CellMask CM = null)
        {
            using (new FuncTrace()) {
                if (pt.Length != gdat.SpatialDimension)
                {
                    throw new ArgumentException("length must be equal to spatial dimension", "pt");
                }
                ilPSP.MPICollectiveWatchDog.Watch(MPI.Wrappers.csMPI.Raw._COMM.WORLD);

                int MpiRank = gdat.CellPartitioning.MpiRank;
                int MpiSize = gdat.CellPartitioning.MpiSize;

                int J = gdat.iLogicalCells.NoOfLocalUpdatedCells;
                int D = gdat.SpatialDimension;

                MultidimensionalArray center = MultidimensionalArray.Create(1, 1, D);  // cell center in global coordinates

                MultidimensionalArray _pt = MultidimensionalArray.Create(1, D);        // point to search for
                for (int d = 0; d < D; d++)
                {
                    _pt[0, d] = pt[d];
                }
                MultidimensionalArray _pt_local = MultidimensionalArray.Create(1, 1, D); // .. in cell-local coordinate
                double[] pt_local = new double[D];


                // sweep over locally updated cells ...
                // ====================================

                int    jL_MinDistCel = 0; // logical cell with minimum distance
                int    jG_MinDistCel = 0; // geometrical cell with minimum distance
                double MinDist       = double.MaxValue;

                int j_Within = -1;
                if (CM == null)
                {
                    CM = CellMask.GetFullMask(gdat);
                }

                foreach (int jL in CM.ItemEnum)
                {
                    foreach (int j in gdat.GetGeometricCellIndices(jL))
                    {
                        // compute distance
                        // ================
                        {
                            var smplx = gdat.iGeomCells.GetRefElement(j);
                            gdat.TransformLocal2Global(smplx.Center, j, 1, center, 0);

                            double dist = 0;
                            for (int d = 0; d < D; d++)
                            {
                                double del = pt[d] - center[0, 0, d];
                                dist += del * del;
                            }

                            dist = Math.Sqrt(dist);

                            if (dist < MinDist)
                            {
                                MinDist       = dist;
                                jL_MinDistCel = jL;
                                jG_MinDistCel = j;
                            }
                        }

                        // transform back into cell
                        // ========================
                        {
                            try {
                                gdat.TransformGlobal2Local(_pt, _pt_local, j, 1, 0);
                                for (int d = 0; d < D; d++)
                                {
                                    pt_local[d] = _pt_local[0, 0, d];
                                }

                                var smplx = gdat.iGeomCells.GetRefElement(j);

                                if (smplx.IsWithin(pt_local))
                                {
                                    j_Within = j;
                                }
                            } catch (ArithmeticException) {
                                // probably outside...
                            }
                        }
                    }
                }

                // ========================================
                // First case: point is inside of some cell
                // ========================================

                int lowestWithinRank = j_Within >= 0 ? MpiRank : int.MaxValue;
                lowestWithinRank = lowestWithinRank.MPIMin(); // lowest rank which found a cell that contains the point:
                //                                               this rank will be the official finder!

                if (lowestWithinRank < MpiSize)
                {
                    LocatPointHelper(gdat, lowestWithinRank, j_Within, out GlobalId, out GlobalIndex, out OnThisProcess);
                    IsInside = true;
                    return;
                }


                // ========================================
                // Second case: point is outside of all cells
                // ========================================

                double MinDistGlobal     = MinDist.MPIMin();
                int    lowestMinimumRank = MinDistGlobal == MinDist ? MpiRank : int.MaxValue;
                lowestMinimumRank = lowestMinimumRank.MPIMin(); // find minimum rank on which the global minimum was reached.
                if (lowestMinimumRank < 0 || lowestMinimumRank >= MpiSize)
                {
                    throw new ApplicationException();
                }

                LocatPointHelper(gdat, lowestMinimumRank, jL_MinDistCel, out GlobalId, out GlobalIndex, out OnThisProcess);
                IsInside = false;
                return;
            }
        }
Esempio n. 12
0
        /// <summary>
        /// Returns an enumeration of geometrical cell chunks (first index an length) for a given cell mask.
        /// </summary>
        /// <param name="CM"></param>
        /// <param name="MaxVecLen"></param>
        /// <param name="ConsecutiveMask"></param>
        /// <returns></returns>
        public static IEnumerable <Tuple <int, int> > GetGeometricCellChunks(this CellMask CM, int MaxVecLen, CellInfo ConsecutiveMask = CellInfo.Undefined)
        {
            var ret = new Mask2GeomChunks_Enumable()
            {
                CM = CM, MaxVecLen = MaxVecLen, ConsecutiveMask = ConsecutiveMask
            };

#if DEBUG
            int      JG   = CM.GridData.iGeomCells.Count;
            BitArray test = new BitArray(JG);
            foreach (var t_i0_len in ret)
            {
                int j0      = t_i0_len.Item1;
                int Len     = t_i0_len.Item2;
                var Flag_j0 = CM.GridData.iGeomCells.InfoFlags[j0] & ConsecutiveMask;
                for (int j = j0; j < j0 + Len; j++)
                {
                    Debug.Assert(test[j] == false); // each geometric cell is touched only once.
                    test[j] = true;
                    var Flag_j = CM.GridData.iGeomCells.InfoFlags[j0] & ConsecutiveMask;
                    Debug.Assert(Flag_j == Flag_j0); // each geometric cell has the same
                }
            }

            BitArray CMmask = CM.GetBitMask();
            int[][]  L2G    = CM.GridData.iLogicalCells.AggregateCellToParts;
            for (int jL = 0; jL < CMmask.Count; jL++)
            {
                if (L2G == null || L2G[jL] == null)
                {
                    int jG = jL;
                    if (CMmask[jL] != test[jG])
                    {
                        var r = new Mask2GeomChunks_Enumable()
                        {
                            CM = CM, MaxVecLen = MaxVecLen, ConsecutiveMask = ConsecutiveMask
                        };

                        foreach (var _t_i0_len in r)
                        {
                            int j0  = _t_i0_len.Item1;
                            int Len = _t_i0_len.Item2;
                            for (int j = j0; j < j0 + Len; j++)
                            {
                                Console.WriteLine(j);
                            }
                        }

                        Debugger.Break();
                    }
                    Debug.Assert(CMmask[jL] == test[jG]);
                }
                else
                {
                    foreach (int jG in L2G[jL])
                    {
                        Debug.Assert(CMmask[jL] == test[jG]);
                    }
                }
            }
#endif
            return(ret);
        }
Esempio n. 13
0
 public void Dispose()
 {
     CMenum.Dispose();
     CMenum = null;
     CM     = null; // object can never be used again.
 }
Esempio n. 14
0
        /// <summary>
        /// computes a global time-step length ("delta t") according to the
        /// Courant-Friedrichs-Lax - criterion, based on a velocity
        /// vector (<paramref name="velvect"/>) and the cell size
        /// this.<see cref="Cells"/>.<see cref="CellData.h_min"/>;
        /// </summary>
        /// <param name="velvect">
        /// components of a velocity vector
        /// </param>
        /// <param name="max">
        /// an upper maximum for the return value; This is useful if the velocity
        /// defined by <paramref name="velvect"/> is 0 or very small everywhere;
        /// </param>
        /// <param name="cm">
        /// optional restriction of domain.
        /// </param>
        /// <returns>
        /// the minimum (over all cells j in all processes) of <see cref="CellData.h_min"/>[j]
        /// over v, where v is the Euclidean norm of a vector build from
        /// <paramref name="velvect"/>;
        /// This vector is evaluated at cell center and all cell vertices.
        /// The return value is the same on all processes;
        /// </returns>
        static public double ComputeCFLTime <T>(this IGridData __gdat, IEnumerable <T> velvect, double max, CellMask cm = null)
            where T : DGField //
        {
            using (var tr = new FuncTrace()) {
                GridData gdat = (GridData)__gdat;

                ilPSP.MPICollectiveWatchDog.Watch(MPI.Wrappers.csMPI.Raw._COMM.WORLD);

                T[] _velvect = velvect.ToArray();

                if (cm == null)
                {
                    cm = CellMask.GetFullMask(gdat);
                }

                int D     = gdat.SpatialDimension;
                var KrefS = gdat.Grid.RefElements;

                // find cfl number on this processor
                // ---------------------------------

                var m_CFL_EvalPoints = new NodeSet[KrefS.Length];
                for (int i = 0; i < KrefS.Length; i++)
                {
                    var Kref = KrefS[i];
                    int N    = Kref.NoOfVertices + 1;

                    MultidimensionalArray vert = MultidimensionalArray.Create(N, D);
                    vert.SetSubArray(Kref.Vertices, new int[] { 0, 0 }, new int[] { N - 2, D - 1 });

                    m_CFL_EvalPoints[i] = new NodeSet(Kref, vert);
                }



                // evaluators an memory for result
                int       VecMax  = 1000;
                DGField[] evalers = new DGField[_velvect.Length];
                MultidimensionalArray[] fieldValues = new MultidimensionalArray[_velvect.Length];
                for (int i = 0; i < _velvect.Length; i++)
                {
                    evalers[i]     = _velvect[i];
                    fieldValues[i] = MultidimensionalArray.Create(VecMax, m_CFL_EvalPoints[0].NoOfNodes);
                }

                var    h_min   = gdat.Cells.h_min;
                int    K       = _velvect.Length;
                double cflhere = max;

                //for (int j = 0; j < J; j += VectorSize) {
                foreach (Chunk chk in cm)
                {
                    int VectorSize = VecMax;
                    for (int j = chk.i0; j < chk.JE; j += VectorSize)
                    {
                        if (j + VectorSize > chk.JE + 1)
                        {
                            VectorSize = chk.JE - j;
                        }
                        VectorSize = gdat.Cells.GetNoOfSimilarConsecutiveCells(CellInfo.RefElementIndex_Mask, j, VectorSize);


                        int iKref = gdat.Cells.GetRefElementIndex(j);
                        int N     = m_CFL_EvalPoints[iKref].GetLength(0);

                        if (fieldValues[0].GetLength(0) != VectorSize)
                        {
                            for (int i = 0; i < _velvect.Length; i++)
                            {
                                fieldValues[i].Allocate(VectorSize, N);
                            }
                        }

                        for (int k = 0; k < K; k++)
                        {
                            evalers[k].Evaluate(j, VectorSize, m_CFL_EvalPoints[iKref], fieldValues[k], 0, 0.0);
                        }

                        // loop over cells ...
                        for (int jj = j; jj < j + VectorSize; jj++)
                        {
                            // loop over nodes ...
                            for (int n = 0; n < N; n++)
                            {
                                double velabs = 0;

                                // loop over velocity components ...
                                for (int k = 0; k < K; k++)
                                {
                                    double v = fieldValues[k][jj - j, n];
                                    velabs += v * v;
                                }

                                velabs = Math.Sqrt(velabs);

                                double cfl = h_min[jj] / velabs;
                                cflhere = Math.Min(cfl, cflhere);
                            }
                        }
                    }
                }

                // find the minimum over all processes via MPI and return
                // ------------------------------------------------------
                double cfltotal;
                unsafe {
                    csMPI.Raw.Allreduce((IntPtr)(&cflhere), (IntPtr)(&cfltotal), 1, csMPI.Raw._DATATYPE.DOUBLE, csMPI.Raw._OP.MIN, csMPI.Raw._COMM.WORLD);
                }
                tr.Info("computed CFL timestep: " + cfltotal);
                return(cfltotal);
            }
        }
Esempio n. 15
0
 /// <summary>
 /// ctor
 /// </summary>
 /// <param name="volMask">
 /// volume mask for those cells which should be contained in the subgrid
 /// </param>
 public SubGrid(CellMask volMask)
 {
     MPICollectiveWatchDog.Watch();
     this.m_VolumeMask = volMask;
     m_GridData        = volMask.GridData;
 }