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