/// <summary> /// <see cref="DGField.FieldInitializer"/> /// </summary> /// <param name="tsi"></param> /// <param name="data"></param> /// <param name="loadedObjects"></param> public override void LoadData(ITimestepInfo tsi, IList <CellFieldDataSet> data, HashSet <object> loadedObjects) { if (loadedObjects.Contains(this)) { return; } this.Basis.Tracker.LoadData(tsi, data, loadedObjects); int MyIndex = tsi.FieldInitializers.IndexOf( this.Initializer, (a, b) => a.Identification.Equals(b.Identification)); XDGFieldInitializer myInfo = (XDGFieldInitializer)tsi.FieldInitializers.Single(info => info.Identification.Equals(this.Identification)); if (this.Basis.Degree == myInfo.BasisInfo.Degree) { XDGField dis = this; LoadCoordinates(data, MyIndex, dis); } else { XDGField Temp = new XDGField(new XDGBasis(this.Basis.Tracker, myInfo.BasisInfo.Degree)); LoadCoordinates(data, MyIndex, Temp); this.Clear(); this.AccLaidBack(1.0, Temp); } loadedObjects.Add(this); }
/// <summary> /// Loads a time-step from the database. /// </summary> /// <remarks> /// By using this method, it is ensured that the loaded/returned fields /// have the same DG polynomial degree as in the database. /// </remarks> public IEnumerable <DGField> LoadFields(ITimestepInfo info, IGridData grdDat, IEnumerable <string> NameFilter = null) { using (var tr = new FuncTrace()) { // check // ===== if (!info.Grid.ID.Equals(grdDat.GridID)) { throw new ArgumentException("Mismatch in Grid."); } // Instantiate // ========== IEnumerable <DGField.FieldInitializer> F2LoadInfo; if (NameFilter != null) { F2LoadInfo = info.FieldInitializers.Where(fi => NameFilter.Contains(fi.Identification, (a, b) => a.Equals(b))); } else { F2LoadInfo = info.FieldInitializers; } IInitializationContext ic = info.Database.Controller.GetInitializationContext(info); var fields = F2LoadInfo.Select(fi => fi.Initialize(ic)).ToArray(); List <DGField> fieldsFlattened = new List <DGField>(); TimestepInfo.FlattenHierarchy(fieldsFlattened, fields); this.LoadFieldData(info, grdDat, fieldsFlattened); return(fieldsFlattened); } }
/// <summary> /// Loads the field with name <paramref name="fieldName"/> within the /// time-step with id <paramref name="timestepGuid"/> from the /// database. /// </summary> /// <param name="gridData"></param> /// <param name="timestepGuid"></param> /// <param name="fieldName"></param> /// <returns></returns> private static DGField GetStoredField(GridData gridData, Guid timestepGuid, string fieldName) { IDatabaseInfo database = gridData.Grid.Database; ITimestepInfo tsi = database.Controller.DBDriver.LoadTimestepInfo( timestepGuid, null, database); return(database.Controller.DBDriver.LoadFields(tsi, gridData, new[] { fieldName }).Single()); }
/// <summary> /// Determines the mean time-step size between <paramref name="timestep"/> /// and <see cref="ITimestepInfoExtensions.Previous"/> /// </summary> /// <param name="timestep"> /// The considered time-step /// </param> /// <returns> /// The average time-step in the given based on /// <see cref="ITimestepInfo.PhysicalTime"/>. /// </returns> public static double GetTimeStepSize(this ITimestepInfo timestep) { #if DEBUG Console.WriteLine("Warning: Computation of time-step size uses averaging at the moment. Ask Björn for details"); #endif ITimestepInfo previous = timestep.Previous(); int noOfSteps = timestep.TimeStepNumber.MajorNumber - previous.TimeStepNumber.MajorNumber; return((timestep.PhysicalTime - previous.PhysicalTime) / noOfSteps); }
/// <summary> /// Retrieves the write time of a physical file associated with an /// ITimestepInfo object. /// </summary> /// <param name="timestep">The timestep in question.</param> /// <returns>The last time the file has been written to disk.</returns> public static DateTime GetTimestepFileWriteTime(ITimestepInfo timestep) { string timestepFolderPath = Path.Combine(timestep.Database.Path, StandardFsDriver.TimestepDir); string timestepFileName = timestep.ID.ToString() + ".ts"; string timestepFilePath = Path.Combine(timestepFolderPath, timestepFileName); return(File.GetLastWriteTime(timestepFilePath)); }
/// <summary> /// Computes the L2 error of field <paramref name="fieldName"/> with /// respect to a field with the same name stored in the time-step with /// <see cref="TimestepNumber"/> <paramref name="timestepNumber"/> within the /// current database. /// </summary> /// <param name="fieldName"> /// The name of the field to be evaluated /// </param> /// <param name="timestepNumber"> /// The time-step containing the reference field /// </param> /// <returns> /// The error of <paramref name="fieldName"/> in the L2 norm. /// </returns> public static Query L2Error(string fieldName, TimestepNumber timestepNumber) { return(delegate(IApplication <AppControl> app, double time) { ITimestepInfo ts = app.CurrentSessionInfo.Timesteps.Single(t => t.TimeStepNumber.Equals(timestepNumber)); DGField field = app.IOFields.Single(f => f.Identification == fieldName); DGField referenceField = GetStoredField(app.GridData, ts.ID, fieldName); return L2Error(fieldName, referenceField)(app, time); }); }
/// <summary> /// returns the DG field from some timestep /// </summary> public static DGField GetField(this ITimestepInfo tsi, string Identification, bool ignoreCase = true) { if (ignoreCase) { return(tsi.Fields.Single(f => f.Identification.ToLowerInvariant().Equals(Identification.ToLowerInvariant()))); } else { return(tsi.Fields.Single(f => f.Identification.Equals(Identification))); } }
/// <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); } } }
/// <summary> /// ctor /// </summary> /// <param name="tst"></param> /// <param name="__FieldName"> /// <see cref="FieldName"/> /// </param> public ForeignGridValue(ITimestepInfo tst, string __FieldName) { FieldName = __FieldName; TimestepID = tst.ID; SessionID = tst.Session.ID; var bla = tst.Database.AlternateDbPaths.ToList(); bla.Insert(0, (tst.Database.Path, null)); this.DbPaths = bla.ToArray(); }
/// <summary> /// Makes each level set load the appropriate <paramref name="data"/> /// for the given <paramref name="tsi"/>. /// </summary> /// <param name="tsi"> /// Information about the time-step /// </param> /// <param name="data"> /// Data to be loaded /// </param> /// <param name="loadedObjects"> /// Cache for already loaded objects /// </param> /// <remarks> /// Causes an update of the level set tracker! /// </remarks> public void LoadData(ITimestepInfo tsi, IList <CellFieldDataSet> data, HashSet <object> loadedObjects) { if (loadedObjects.Contains(this)) { return; } foreach (var Ls in this.LevelSets) { Ls.As <LevelSet>().LoadData(tsi, data, loadedObjects); } this.UpdateTracker(0.0); loadedObjects.Add(this); }
/// <summary> /// <see cref="DGField.FieldInitializer"/> /// </summary> /// <param name="tsi"></param> /// <param name="data"></param> /// <param name="loadedObjects"></param> public override void LoadData(ITimestepInfo tsi, IList <CellFieldDataSet> data, HashSet <object> loadedObjects) { if (loadedObjects.Contains(this)) { return; } this.Basis.Tracker.LoadData(tsi, data, loadedObjects); int MyIndex = tsi.FieldInitializers.IndexOf( this.Initializer, (a, b) => a.Identification.Equals(b.Identification)); XDGFieldInitializer myInfo = (XDGFieldInitializer)tsi.FieldInitializers.Single(info => info.Identification.Equals(this.Identification)); if (MyIndex >= 0) { int J = this.GridDat.iLogicalCells.NoOfLocalUpdatedCells; for (int j = 0; j < J; j++) { //double[] coords_j = data[j].DGCoordinateData[MyIndex]; //double[] coords_j = data[j].DGCoordinateData[MyIndex].Data; double[] coords_j = data[j].GetDGCoordinates(MyIndex); Debug.Assert(data[j].GlobalID == this.GridDat.iLogicalCells.GetGlobalID(j)); this.DeserializeDGcoords(j, coords_j); } } else { Console.Error.WriteLine("Unable to load field '{0}'; initializing with zeros.", this.Identification); this.Coordinates.Clear(); } /* * if (this.Basis.Degree == myInfo.BasisInfo.Degree) { * XDGField dis = this; * LoadCoordinates(data, MyIndex, dis); * } else { * XDGField Temp = new XDGField(new XDGBasis(this.Basis.Tracker, myInfo.BasisInfo.Degree)); * LoadCoordinates(data, MyIndex, Temp); * this.Clear(); * this.AccLaidBack(1.0, Temp); * }*/ loadedObjects.Add(this); }
/// <summary> /// Supports the loading of DG fields from database, not intended for /// direct user interaction. /// </summary> public virtual void LoadData(ITimestepInfo tsi, IList <CellFieldDataSet> data, HashSet <object> loadedObjects) { if (loadedObjects.Contains(this)) { return; } if (this.Identification == null || this.Identification.Length <= 0) { throw new NotSupportedException("unable to load a timestep into unnamed fields."); } int MyIndex = tsi.FieldInitializers.IndexOf( this.Initializer, (a, b) => a.Identification.Equals(b.Identification)); if (MyIndex >= 0) { int J = this.GridDat.iLogicalCells.NoOfLocalUpdatedCells; for (int j = 0; j < J; j++) { //double[] coords_j = data[j].DGCoordinateData[MyIndex]; //double[] coords_j = data[j].DGCoordinateData[MyIndex].Data; double[] coords_j = data[j].GetDGCoordinates(MyIndex); Debug.Assert(data[j].GlobalID == this.GridDat.iLogicalCells.GetGlobalID(j)); int Nt = this.Basis.GetLength(j); int N = Math.Min(coords_j.Length, Nt); int n = 0; for (; n < N; n++) { this.Coordinates[j, n] = coords_j[n]; } for (; n < Nt; n++) { this.Coordinates[j, n] = 0.0; } } } else { Console.WriteLine("Unable to load field '{0}'; initializing with zeros.", this.Identification); } loadedObjects.Add(this); }
/// <summary> /// Constructor /// </summary> /// <param name="sessionPath">Path where everything is stored</param> /// <param name="session">The session from the database</param> /// <param name="input"> /// Lenghts --> [0]: numOfPoints, [1]: maxIterations + 1, [2]: 5 /// [2]: x | y | function values | second derivatives | step sizes /// </param> /// <param name="inputExtended"> /// Lenghts --> [0]: numOfPoints, [1]: 3 /// [1]: IterationsNeeded | Converged | jCell /// </param> public LevelSetReconstruction(string sessionPath, ISessionInfo session, MultidimensionalArray input, MultidimensionalArray inputExtended) { this.SessionPath = sessionPath; this.Session = session; this.input = input; this.inputExtended = inputExtended; ITimestepInfo myTimestep = session.Timesteps.Last(); this.gridData = (GridData)myTimestep.Fields.First().GridDat; if (myTimestep.Fields.Where(f => f.Identification == "rho").SingleOrDefault() is XDGField) { XDGField densityField = (XDGField)myTimestep.Fields.Where(f => f.Identification == "rho").SingleOrDefault(); this.densityField = new SinglePhaseField(new Basis(gridData, densityField.Basis.Degree), "rho"); this.densityField.Acc(1.0, densityField.GetSpeciesShadowField("B")); } else { this.densityField = (SinglePhaseField)myTimestep.Fields.Where(f => f.Identification == "rho").SingleOrDefault(); } this.geometryLevelSetField = (SinglePhaseField)myTimestep.Fields.Where(f => f.Identification == "levelSet").SingleOrDefault(); }
/// <summary> /// Deletes a time-step from its database. /// </summary> /// <param name="timestep">The time-step to be deleted.</param> /// <param name="force"> /// If true, the user will not be asked for confirmation /// </param> public static void Delete(this ITimestepInfo timestep, bool force = false) { bool sure = true; if (!force) { Console.WriteLine("Time-step: " + timestep.ToString()); Console.Write("Do you really want to delete this time-step? [y/n]: "); string line = Console.ReadLine(); sure = line.ToLower().Equals("y"); } if (sure) { TimestepNumber number = timestep.TimeStepNumber; timestep.Database.Controller.DeleteTimestep(timestep); Console.WriteLine("Time-step " + number + " deleted."); } else { Console.WriteLine("Session delete canceled."); } }
/// <summary> /// Constructor /// </summary> /// <param name="sessionPath">Path where everything is stored</param> /// <param name="tsi">A time step from the database</param> public InflectionPointFinder(string sessionPath, ITimestepInfo tsi) { this.SessionPath = sessionPath; this.tsi = tsi; this.gridData = (GridData)tsi.Fields.First().GridDat; if (tsi.Fields.Where(f => f.Identification == "rho").SingleOrDefault() is XDGField) { XDGField densityField = (XDGField)tsi.Fields.Where(f => f.Identification == "rho").SingleOrDefault(); XDGField avField = (XDGField)tsi.Fields.Where(f => f.Identification == "artificialViscosity").SingleOrDefault(); this.densityField = new SinglePhaseField(new Basis(gridData, densityField.Basis.Degree), "rho"); this.densityField.Acc(1.0, densityField.GetSpeciesShadowField("B")); this.levelSetField = (SinglePhaseField)tsi.Fields.Where(f => f.Identification == "levelSet").SingleOrDefault(); } else { this.densityField = (SinglePhaseField)tsi.Fields.Where(f => f.Identification == "rho").SingleOrDefault(); this.avField = (SinglePhaseField)tsi.Fields.Where(f => f.Identification == "artificialViscosity").SingleOrDefault(); this.levelSetField = (SinglePhaseField)tsi.Fields.Where(f => f.Identification == "levelSet").SingleOrDefault(); } }
/// <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) { timestepDatabaseDriver.LoadFieldData(info, grdDat, PreAllocatedFields); }
/// <summary> /// Setting <see cref="RestartInfo"/> /// </summary> public void SetRestart(ITimestepInfo tsi) { this.InitialValues.Clear(); this.InitialValues_Evaluators.Clear(); this.RestartInfo = Tuple.Create(tsi.Session.ID, tsi.TimeStepNumber); }
/// <summary> /// Updates all columns related to convergence plots /// </summary> public void Update() { // Get all sessions which are successfully terminated // ================================================== var SuccSessions = owner.Sessions.Where(sess => sess.SuccessfulTermination == true).ToArray(); // Group the sessions according to polynomial degree // ================================================= System.Func <int[], int[], bool> eqFunc = (A, B) => ArrayTools.AreEqual(A, B); var comp = eqFunc.ToEqualityComparer(); var SessionGroups = SuccSessions.GroupBy(GetDGDegreeKey, comp).ToArray(); // Spatial convergence for each session group // ========================================== // intermediate result storage // 1st key: Field name // 2nd key: session name // value: error norm var Errors = new Dictionary <string, Dictionary <Guid, double> >(); foreach (IEnumerable <ISessionInfo> spatialSeries in SessionGroups) { if (spatialSeries.Count() <= 1) { continue; } ITimestepInfo[] tsiS = spatialSeries.Select(sess => sess.Timesteps.Last()).ToArray(); // find DG field identifications which are present in _all_ timesteps var commonFieldIds = new HashSet <string>(); foreach (var fi in tsiS[0].FieldInitializers) { string id = fi.Identification; bool containedInOthers = true; foreach (var tsi in tsiS.Skip(1)) { if (tsi.FieldInitializers.Where(fii => fii.Identification == id).Count() <= 0) { containedInOthers = false; } } if (containedInOthers) { commonFieldIds.Add(id); } } string[] fieldIds = commonFieldIds.ToArray(); // compute L2-errors DGFieldComparison.ComputeErrors(fieldIds, tsiS, out double[] hS, out var DOFs, out var ERRs, out var tsiIdS); // record errors foreach (var id in fieldIds) { Dictionary <Guid, double> err_id; if (!Errors.TryGetValue(id, out err_id)) { err_id = new Dictionary <Guid, double>(); Errors.Add(id, err_id); } for (int iGrd = 0; iGrd < hS.Length; iGrd++) { ITimestepInfo tsi = tsiS.Single(t => t.ID == tsiIdS[iGrd]); ISessionInfo sess = tsi.Session; err_id.Add(sess.ID, ERRs[id][iGrd]); } } } // Set L2 error columns in session table // ===================================== foreach (string fieldName in Errors.Keys) { string colName = "L2Error_" + fieldName; if (owner.AdditionalSessionTableColums.ContainsKey(colName)) { owner.AdditionalSessionTableColums.Remove(colName); } var ErrorsCol = Errors[fieldName]; owner.AdditionalSessionTableColums.Add(colName, delegate(ISessionInfo s) { object ret = 0.0; if (ErrorsCol.ContainsKey(s.ID)) { ret = ErrorsCol[s.ID]; } return(ret); }); } }
/// <summary> /// Returns null. /// </summary> /// <param name="timestepGuid"></param> /// <returns></returns> public IInitializationContext GetInitializationContext(ITimestepInfo timestepGuid) { return(null); }
/// <summary> /// Selects the next time-step stored in the session. /// </summary> /// <param name="timestep"> /// The current time-step /// </param> /// <returns> /// The first full time-step in the current session after /// <paramref name="timestep"/>. /// </returns> public static ITimestepInfo Next(this ITimestepInfo timestep) { return(timestep.Session.Timesteps.WithoutSubSteps().SkipWhile(t => t != timestep).Second()); }
/// <summary> /// Selects the previous time-step stored in the session. /// </summary> /// <param name="timestep"> /// The current time-step /// </param> /// <returns> /// The last full time-step in the current session before /// <paramref name="timestep"/>. /// </returns> public static ITimestepInfo Previous(this ITimestepInfo timestep) { return(timestep.Session.Timesteps.WithoutSubSteps().TakeWhile(t => t != timestep).Last()); }
/// <summary> /// Opens the directory where the export for the selected /// <paramref name="timestep"/> are stored in the explorer. /// </summary> /// <param name="timestep"> /// The selected time-step. /// </param> /// <remarks> /// Obviously, this only works in Windows environments. /// </remarks> public static void OpenExportDirectory(this ITimestepInfo timestep) { Process.Start(Utils.GetExportDirectory(timestep.Session)); }
/// <summary> /// Convenience interface to create a /// <see cref="SessionExportInstruction"/> for a single time-step. /// </summary> /// <param name="timestep"> /// The time-step to be exported /// </param> /// <returns> /// A new instance of <see cref="SessionExportInstruction"/> for the /// given <paramref name="timestep"/> /// </returns> public static SessionExportInstruction Export(this ITimestepInfo timestep) { return(new SessionExportInstruction(timestep.Session).WithTimesteps(timestep.TimeStepNumber)); }
/// <summary> /// Loads a time-step from the database. /// </summary> /// <remarks> /// By using this method, it is ensured that the loaded/returned fields /// have the same DG polynomial degree as in the database. /// </remarks> public IEnumerable <DGField> LoadFields(ITimestepInfo info, IGridData grdDat, IEnumerable <string> NameFilter = null) { return(timestepDatabaseDriver.LoadFields(info, grdDat, NameFilter)); }
/// <summary> /// Does nothing /// </summary> /// <param name="timestep"></param> public void DeleteTimestep(ITimestepInfo timestep) { }