/// <summary>
        /// Loads a time-step from the database into previously allocated
        /// DG-fields (<paramref name="PreAllocatedFields"/>).
        /// </summary>
        public void LoadFieldData(ITimestepInfo info, IGridData grdDat, IEnumerable <DGField> PreAllocatedFields)
        {
            using (var tr = new FuncTrace())
            {
                DGField[]      Fields        = PreAllocatedFields.ToArray(); // enforce 'evaluation' of the enum (in the case it is some delayed linq-expr).
                List <DGField> FieldsFlatten = new List <DGField>();
                TimestepInfo.FlattenHierarchy(FieldsFlatten, Fields);
                foreach (var f in FieldsFlatten)
                {
                    if (!Fields.Contains(f, (a, b) => object.ReferenceEquals(a, b)))
                    {
                        throw new ArgumentException("Unable to load timestep: field '" + f.Identification + "', which is required by at least one of the given fields, must also be contained in the given list of fields.", "PreAllocatedFields");
                    }
                }

                // Load data vector
                // ================
                var partition = grdDat.CellPartitioning;
                var DataVec   = this.Driver.LoadVector <CellFieldDataSet>(info.StorageID, ref partition);

                // Permute data vector
                // ===================


                var SortedDataVec = new CellFieldDataSet[DataVec.Count];

                {
                    // tau   is the GlobalID-permutation that we have for the loaded vector
                    // sigma is the current GlobalID-permutation of the grid
                    var sigma = grdDat.CurrentGlobalIdPermutation;
                    var tau   = new Permutation(DataVec.Select(cd => cd.GlobalID).ToArray(), csMPI.Raw._COMM.WORLD);

                    // compute resorting permutation
                    Permutation invSigma  = sigma.Invert();
                    Permutation Resorting = invSigma * tau;
                    tau      = null;
                    invSigma = null;

                    // put dg coordinates into right order
                    Resorting.ApplyToVector(DataVec, SortedDataVec);
                }


                // Load the fields
                // ===============
                HashSet <object> loadedObjects = new HashSet <object>(ReferenceComparer.Instance);

                foreach (var Field in Fields)
                {
                    Field.LoadData(info, SortedDataVec, loadedObjects);
                }
            }
        }
示例#2
0
        static bool AreCellsEqual(GridCommons A, GridCommons B)
        {
            if (object.ReferenceEquals(A, B))
            {
                return(true);
            }
            if ((A == null) != (B == null))
            {
                return(false);
            }


            if (A.Cells == null)
            {
                throw new ArgumentException();
            }
            int A_NumberOfBcCells = A.NumberOfBcCells;

            int match = 1;

            {
                // load cells of grid B, if required
                // ---------------------------------

                Cell[] B_Cells;
                if (B.Cells == null)
                {
                    throw new Exception("Cells are not initialized");
                }
                else
                {
                    B_Cells = B.Cells;
                }

                if (A.Cells.Length != B_Cells.Length)
                {
                    throw new ApplicationException();
                }

                // put the cells of B into the same order as those of A
                // ----------------------------------------------------

                {
                    // tau   is the GlobalID-permutation that we have for the loaded vector
                    // sigma is the current GlobalID-permutation of the grid
                    var sigma = new Permutation(A.Cells.Select(cell => cell.GlobalID).ToArray(), csMPI.Raw._COMM.WORLD);
                    var tau   = new Permutation(B_Cells.Select(cell => cell.GlobalID).ToArray(), csMPI.Raw._COMM.WORLD);

                    if (sigma.TotalLength != tau.TotalLength)
                    {
                        // should have been checked already
                        throw new ArgumentException();
                    }

                    // compute resorting permutation
                    Permutation invSigma  = sigma.Invert();
                    Permutation Resorting = invSigma * tau;
                    tau      = null; // Werfen wir sie dem GC zum Fraße vor!
                    invSigma = null;

                    // put dg coordinates into right order
                    Resorting.ApplyToVector(B_Cells.CloneAs(), B_Cells);
                }

                // compare cells
                // -------------

                for (int j = 0; j < A.Cells.Length; j++)
                {
                    Cell Ca = A.Cells[j];
                    Cell Cb = B_Cells[j];

                    Debug.Assert(Ca.GlobalID == Cb.GlobalID);

                    if (!ArrayTools.ListEquals(Ca.NodeIndices, Cb.NodeIndices, (ia, ib) => ia == ib))
                    {
                        match = 0;
                        break;
                    }

                    if (Ca.Type != Cb.Type)
                    {
                        match = 0;
                        break;
                    }

                    if (Ca.CellFaceTags != null || Cb.CellFaceTags != null)
                    {
                        CellFaceTag[] CFTA = Ca.CellFaceTags != null ? Ca.CellFaceTags : new CellFaceTag[0];
                        CellFaceTag[] CFTB = Cb.CellFaceTags != null ? Cb.CellFaceTags : new CellFaceTag[0];

                        if (CFTA.Length != CFTB.Length)
                        {
                            match = 0;
                            break;
                        }

                        bool setMatch = true;
                        for (int i1 = 0; i1 < CFTA.Length; i1++)
                        {
                            bool b = false;
                            for (int j1 = 0; j1 < CFTB.Length; j1++)
                            {
                                if (CFTA[i1].Equals(CFTB[j1]))
                                {
                                    b = true;
                                    break;
                                }
                            }

                            if (b == false)
                            {
                                setMatch = false;
                                break;
                            }
                        }

                        if (!setMatch)
                        {
                            match = 0;
                            break;
                        }
                    }


                    double h      = Math.Min(Ca.TransformationParams.MindistBetweenRows(), Cb.TransformationParams.MindistBetweenRows());
                    double L2Dist = Ca.TransformationParams.L2Dist(Cb.TransformationParams);
                    if (L2Dist > h * 1.0e-9)
                    {
                        match = 0;
                        break;
                    }
                }
            }


            if (A_NumberOfBcCells > 0)
            {
                BCElement[] B_BcCells;
                if (B.BcCells == null && !B.BcCellsStorageGuid.Equals(Guid.Empty))
                {
                    throw new Exception("Bc Cells are not initialized");
                }
                else
                {
                    B_BcCells = B.BcCells;
                }

                if (A.BcCells.Length != B_BcCells.Length)
                {
                    throw new ApplicationException("Internal error.");
                }


                // put the cells of B into the same order as those of A
                // ----------------------------------------------------

                {
                    long Offset = A.NumberOfCells_l;

                    // tau   is the GlobalID-permutation that we have for the loaded vector
                    // sigma is the current GlobalID-permutation of the grid
                    var sigma = new Permutation(A.BcCells.Select(cell => cell.GlobalID - Offset).ToArray(), csMPI.Raw._COMM.WORLD);
                    var tau   = new Permutation(B_BcCells.Select(cell => cell.GlobalID - Offset).ToArray(), csMPI.Raw._COMM.WORLD);

                    if (sigma.TotalLength != tau.TotalLength)
                    {
                        // should have been checked already
                        throw new ArgumentException();
                    }

                    // compute resorting permutation
                    Permutation invSigma  = sigma.Invert();
                    Permutation Resorting = invSigma * tau;
                    tau      = null; // Werfen wir sie dem GC zum Fraße vor!
                    invSigma = null;

                    // put dg coordinates into right order
                    Resorting.ApplyToVector(B_BcCells.CloneAs(), B_BcCells);
                }


                // compare cells
                // -------------

                for (int j = 0; j < A.BcCells.Length; j++)
                {
                    BCElement Ca = A.BcCells[j];
                    BCElement Cb = B_BcCells[j];

                    Debug.Assert(Ca.GlobalID == Cb.GlobalID);

                    if (!ArrayTools.ListEquals(Ca.NodeIndices, Cb.NodeIndices, (ia, ib) => ia == ib))
                    {
                        match = 0;
                        break;
                    }

                    if (Ca.Type != Cb.Type)
                    {
                        match = 0;
                        break;
                    }

                    if (Ca.Conformal != Cb.Conformal)
                    {
                        match = 0;
                        break;
                    }

                    if (Ca.EdgeTag != Cb.EdgeTag)
                    {
                        match = 0;
                        break;
                    }


                    if (Ca.NeighCell_GlobalIDs != null || Cb.NeighCell_GlobalIDs != null)
                    {
                        long[] NgA = Ca.NeighCell_GlobalIDs != null ? Ca.NeighCell_GlobalIDs : new long[0];
                        long[] NgB = Cb.NeighCell_GlobalIDs != null ? Cb.NeighCell_GlobalIDs : new long[0];

                        if (NgA.Length != NgB.Length)
                        {
                            match = 0;
                            break;
                        }

                        bool setMatch = true;
                        for (int i1 = 0; i1 < NgA.Length; i1++)
                        {
                            bool b = false;
                            for (int j1 = 0; j1 < NgB.Length; j1++)
                            {
                                if (NgA[i1] == NgB[j1])
                                {
                                    b = true;
                                    break;
                                }
                            }

                            if (b == false)
                            {
                                setMatch = false;
                                break;
                            }
                        }

                        if (!setMatch)
                        {
                            match = 0;
                            break;
                        }
                    }


                    double h      = Math.Min(Ca.TransformationParams.MindistBetweenRows(), Cb.TransformationParams.MindistBetweenRows());
                    double L2Dist = Ca.TransformationParams.L2Dist(Cb.TransformationParams);
                    if (L2Dist > h * 1.0e-9)
                    {
                        match = 0;
                        break;
                    }
                }
            }


            match = match.MPIMin();
            return(match > 0);
        }
示例#3
0
        /// <summary>
        /// Apply the resorting (only mesh redistribution between MPI processors, no mesh adaptation)
        /// </summary>
        public void Resort(Permutation r, IGridData NewGrid)
        {
            using (new FuncTrace()) {
                this.GridAdaptation   = false;
                this.Resorting        = r;
                this.InverseResorting = r.Invert();
                m_OldGrid             = null;
                m_OldTracker          = null;
                m_NewGrid             = NewGrid;
                m_newJ = m_NewGrid.iLogicalCells.NoOfLocalUpdatedCells;


                // fix the sequence in which we serialize/de-serialize fields
                string[] FieldNames = this.m_oldDGFieldData.Keys.ToArray();
                int      NoFields   = FieldNames.Length;

                // format data for serialization
                double[][] oldFieldsData = new double[m_oldJ][];
                {
                    double[][][] oldFields = FieldNames.Select(rstring => this.m_oldDGFieldData[rstring]).ToArray();

                    for (int j = 0; j < m_oldJ; j++)
                    {
                        int Ntot = 0;
                        for (int iF = 0; iF < NoFields; iF++)
                        {
                            Ntot += oldFields[iF][j].Length;
                        }

                        double[] data_j = new double[Ntot + NoFields];
                        int      cnt    = 0;
                        for (int iF = 0; iF < NoFields; iF++)
                        {
                            double[] data_iF_j = oldFields[iF][j];
                            int      Nj        = data_iF_j.Length;
                            data_j[cnt] = Nj;
                            cnt++;
                            for (int n = 0; n < Nj; n++)
                            {
                                data_j[cnt] = data_iF_j[n];
                                cnt++;
                            }
                        }
                        oldFieldsData[j] = data_j;
                    }
                    oldFields        = null;
                    m_oldDGFieldData = null;
                }

                // redistribute data
                double[][] newFieldsData = new double[m_newJ][];
                {
                    Resorting.ApplyToVector(oldFieldsData, newFieldsData, m_NewGrid.CellPartitioning);
                    oldFieldsData = null;
                    Debug.Assert(newFieldsData.Length == m_newJ);
                }

                // re-format re-distributed data
                m_newDGFieldData_OnlyRedist = new Dictionary <string, double[][]>();
                {
                    double[][][] newFields = new double[FieldNames.Length][][];
                    for (int iF = 0; iF < NoFields; iF++)
                    {
                        newFields[iF] = new double[m_newJ][];
                    }
                    for (int j = 0; j < m_newJ; j++)
                    {
                        double[] data_j = newFieldsData[j];

                        int cnt = 0;
                        for (int iF = 0; iF < NoFields; iF++)
                        {
                            int Nj = (int)data_j[cnt];
                            cnt++;
                            double[] data_iF_j = new double[Nj];
                            for (int n = 0; n < Nj; n++)
                            {
                                data_iF_j[n] = data_j[cnt];
                                cnt++;
                            }
                            newFields[iF][j] = data_iF_j;
                        }
                        Debug.Assert(cnt == data_j.Length);
                    }

                    for (int iF = 0; iF < NoFields; iF++)
                    {
                        m_newDGFieldData_OnlyRedist.Add(FieldNames[iF], newFields[iF]);
                    }
                }
            }
        }