Пример #1
0
        /// <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
        /// <summary>
        /// Saves a time-step to the database's persistent memory.
        /// </summary>
        /// <param name="_tsi">Contains Id etc.</param>
        public void SaveTimestep(TimestepInfo _tsi)
        {
            using (var tr = new FuncTrace())
            {
                if (!(_tsi.ID.Equals(Guid.Empty) && _tsi.StorageID.Equals(Guid.Empty)))
                {
                    throw new ArgumentException("Timestep is already saved in database");
                }
                var fields  = _tsi.Fields.ToArray();
                var GridDat = fields[0].GridDat;

                {
                    List <DGField> FieldsFlatten = new List <DGField>();
                    TimestepInfo.FlattenHierarchy(FieldsFlatten, fields);
                    foreach (var f in FieldsFlatten)
                    {
                        if (!object.ReferenceEquals(f.GridDat, GridDat))
                        {
                            throw new ArgumentException("mismatch in GridData object.");
                        }

                        if (!fields.Contains(f, (a, b) => object.ReferenceEquals(a, b)))
                        {
                            // here, we ensure that the 'fields' -- list is complete, i.e.
                            // that the flatten hierarchy contains no field which is not already a memeber of 'fields'.
                            // The purpose is e.g. to prevent saving an XDG field without the required level-set field.
                            throw new ArgumentException(
                                      "Unable to save 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.",
                                      "_tsi");
                        }
                    }
                }

                // build vector
                // ============
                int J           = GridDat.iLogicalCells.NoOfLocalUpdatedCells;
                var vec         = new CellFieldDataSet[J];
                var _fields     = fields.ToArray();
                int NF          = _fields.Length;
                var Permutation = GridDat.CurrentGlobalIdPermutation.Values;
                for (int j = 0; j < J; j++)
                { // loop over cells
                    vec[j]          = new CellFieldDataSet();
                    vec[j].GlobalID = Permutation[j];
                    //vec[j].DGCoordinateData = new CellFieldDataSet.CellFieldData[NF];
                    for (int idxF = 0; idxF < NF; idxF++)
                    { // loop over fields
                        var      field  = _fields[idxF];
                        int      N      = field.Basis.GetLength(j);
                        double[] Coords = new double[N];
                        for (int n = 0; n < N; n++)
                        {
                            Coords[n] = field.Coordinates[j, n];
                        }
                        //vec[j].DGCoordinateData[idxF] = new CellFieldDataSet.CellFieldData() {
                        //    Data = Coords
                        //};
                        vec[j].AppendDGCoordinates(Coords);
                        Debug.Assert(ArrayTools.ListEquals(Coords, vec[j].GetDGCoordinates(idxF)));
                    }
                }

                // Save dg coordinates
                // ===================
                Guid VectorGuid = Driver.SaveVector(vec);
                _tsi.StorageID = VectorGuid;


                // Save state object
                // =================
                _tsi.ID = Guid.NewGuid().MPIBroadcast(0);
                Exception e = null;
                if (MyRank == 0)
                {
                    try
                    {
                        //tsi = new TimestepInfo(physTime, currentSession, TimestepNo, fields, VectorGuid);
                        using (var s = fsDriver.GetTimestepStream(true, _tsi.ID))
                        {
                            Driver.Serialize(s, _tsi, typeof(TimestepInfo));
                            s.Close();
                        }
                    }
                    catch (Exception ee)
                    {
                        e = ee;
                        Console.Error.WriteLine(ee.GetType().Name + " on rank " + MyRank + " saving time-step " + _tsi.TimeStepNumber + ": " + ee.Message);
                        Console.Error.WriteLine(ee.StackTrace);
                    }
                }
                e.ExceptionBcast();

                // log session
                // ===========
                SessionInfo currentSession = (SessionInfo)(_tsi.Session); // hack
                if (MyRank == 0)
                {
                    try
                    {
                        currentSession.LogTimeStep(_tsi.ID);
                    }
                    catch (Exception ee)
                    {
                        e = ee;
                        Console.Error.WriteLine(ee.GetType().Name + " on rank " + MyRank + " saving time-step " + _tsi.TimeStepNumber + ": " + ee.Message);
                        Console.Error.WriteLine(ee.StackTrace);
                    }
                }
                e.ExceptionBcast();

                _tsi.Database = currentSession.Database;
            }
        }