protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt) { using (new FuncTrace()) { if (dt <= 0) { NoOfTimesteps = 10000; EndTime = endTime; dt = dt_input; //if (TimestepNo < 3) // dt /= 3; if (EndTime - phystime < dt) { dt = EndTime - phystime; } } if (TimestepNo % 100 == 0) { Console.Write("Timestep " + TimestepNo + " ..."); } timeStepper.UpdateTimeInfo(new TimeInformation(TimestepNo, phystime, dt)); timeStepper.Perform(dt); if (TimestepNo % 100 == 0) { Console.WriteLine("finished"); } // Plot and print L2 Error Norm if (EndTime - phystime - dt < 1E-10) { L2error = u.L2Error(Jump, 30); Console.WriteLine("L2Error:" + L2error); } // TEST //Console.Write("Timestep " + TimestepNo + " ..."); //timeStepper.Perform(dt); //Console.WriteLine("finished"); //L2error = u.L2Error(Jump, 30); //Console.WriteLine("L2Error:" + L2error); //if (TimestepNo == NoOfTimesteps) // Console.ReadKey(); return(dt); } }
/// <summary> /// L2 error with respect to given reference solution. The quadrature /// is determined from the settings in <see cref="IBMControl"/> /// </summary> /// <param name="fieldName"></param> /// <param name="referenceSolution"></param> /// <returns></returns> public static Query L2Error(string fieldName, Func <double[], double, double> referenceSolution) { return(delegate(IApplication <AppControl> app, double time) { IProgram <CNSControl> program = app as IProgram <CNSControl>; if (program == null) { throw new Exception(); } ImmersedSpeciesMap speciesMap = program.SpeciesMap as ImmersedSpeciesMap; IBMControl control = program.Control as IBMControl; if (speciesMap == null || control == null) { throw new Exception( "Query is only valid for immersed boundary runs"); } SpeciesId species = speciesMap.Tracker.GetSpeciesId(control.FluidSpeciesName); int order = control.LevelSetQuadratureOrder; CellQuadratureScheme scheme = speciesMap.QuadSchemeHelper.GetVolumeQuadScheme( species, true, speciesMap.SubGrid.VolumeMask); DGField dgField = app.IOFields.Single(f => f.Identification == fieldName); return dgField.L2Error(referenceSolution.Vectorize(time), order, scheme); }); }
/// <summary> /// L2Error w.r.t. a 3D-function <paramref name="f"/> of a DG-Field /// </summary> public static double L2Error(this DGField u, _3D f) { if (u.Basis.GridDat.SpatialDimension != 3) { throw new ArgumentException("mismatch in spatial dimension"); } return(u.L2Error(f.Vectorize())); }
/// <summary> /// L2Error with respect to <paramref name="AnalyticSolution"/>. /// </summary> /// <param name="f"></param> /// <param name="AnalyticSolution"> /// If null, nothing will be done. /// </param> /// <param name="QuadOrder"></param> /// <param name="ResidualKey"> /// Optional parameter for key of residual. /// If null, the name of <paramref name="f"/> will be used as key. /// </param> public void ComputeL2Error(DGField f, Func <double[], double> AnalyticSolution, int QuadOrder, string ResidualKey = null) { if (AnalyticSolution != null) { string key = GetDictionaryKey(Residualtype.L2Error, f.Identification, ResidualKey); double error = f.L2Error(AnalyticSolution.Vectorize(), QuadOrder); m_Residuals[key] = error; } }
/// <summary> /// Computes the kinetic energy stored in the bulk of a multi-phase flow field. /// </summary> /// <param name="Velocity"></param> /// <param name="rho">Density of the fluids, ordering in the array correlates with species /// ordering in the level-set tracker, see <see cref="LevelSetTracker.SpeciesIdS"/>. /// </param> /// <param name="lsTrk"></param> /// <param name="momentFittingOrder"></param> public static double GetKineticEnergy <T>(LevelSetTracker lsTrk, IEnumerable <T> Velocity, double[] rho, int momentFittingOrder, int HistInd = 1) where T : DGField // { using (new FuncTrace()) { int D = lsTrk.GridDat.SpatialDimension; if (Velocity.Count() != D) { throw new ArgumentException(); } if (lsTrk.SpeciesIdS.Count != rho.Length) { throw new ArgumentException(); } //int order = 0; //if (lsTrk.GetXQuadFactoryHelper(momentFittingVariant).GetCachedVolumeOrders(0).Length > 0) { // order = lsTrk.GetXQuadFactoryHelper(momentFittingVariant).GetCachedVolumeOrders(0).Max(); //} //order = Math.Max(order, Velocity.ElementAt(0).Basis.Degree * 2); var SchemeHelper = lsTrk.GetXDGSpaceMetrics(lsTrk.SpeciesIdS.ToArray(), momentFittingOrder, HistInd).XQuadSchemeHelper; //var SchemeHelper = new XQuadSchemeHelper(lsTrk, momentFittingVariant, lsTrk.SpeciesIdS.ToArray()); double kinE = 0.0; for (int iSpc = 0; iSpc < lsTrk.SpeciesIdS.Count; iSpc++) { double _rho = rho[iSpc]; SpeciesId spId = lsTrk.SpeciesIdS[iSpc]; var scheme = SchemeHelper.GetVolumeQuadScheme(spId); for (int d = 0; d < D; d++) { DGField U = Velocity.ElementAt(d); if (U is XDGField) { if (!object.ReferenceEquals((U as XDGField).Basis.Tracker, lsTrk)) { throw new ArgumentException(); } U = (U as XDGField).GetSpeciesShadowField(spId); } kinE += U.L2Error(null, momentFittingOrder, scheme).Pow2() * _rho * 0.5; } } return(kinE); } }
/// <summary> /// L2Error w.r.t. a function <paramref name="f"/> of a DG-Field /// </summary> public static double L2Error(this DGField u, Func <double[], double> f) { return(u.L2Error(f.Vectorize())); }