/// <summary> /// Instantiates the correct sub-class of <see cref="FluxBuilder"/> /// corresponding to the selected <paramref name="flux"/>. /// </summary> /// <param name="flux"> /// The flux for which the builder should be instantiated. /// </param> /// <param name="control"> /// Configuration options /// </param> /// <param name="boundaryMap"> /// Information about boundary conditions /// </param> /// <param name="speciesMap"> /// Mapping of different species int he domain /// </param> /// <returns> /// An instance of a flux builder that builds fluxes /// corresponding to the given <paramref name="flux"/>. /// </returns> public static FluxBuilder GetBuilder(this ConvectiveFluxTypes flux, CNSControl control, BoundaryConditionMap boundaryMap, ISpeciesMap speciesMap) { switch (flux) { case ConvectiveFluxTypes.Rusanov: return(new RusanovFluxBuilder(control, boundaryMap, speciesMap)); case ConvectiveFluxTypes.HLL: return(new HLLFluxBuilder(control, boundaryMap, speciesMap)); case ConvectiveFluxTypes.HLLC: return(new HLLCFluxBuilder(control, boundaryMap, speciesMap)); case ConvectiveFluxTypes.OptimizedHLLC: return(new OptimizedHLLCFLuxBuilder(control, boundaryMap, speciesMap)); case ConvectiveFluxTypes.Godunov: return(new GodunovFluxBuilder(control, boundaryMap, speciesMap)); case ConvectiveFluxTypes.MovingFrameRusanov: return(new MovingFrameRusanovFluxBuilder(control, boundaryMap, speciesMap)); case ConvectiveFluxTypes.None: return(NullFluxBuilder.Instance); default: throw new Exception("Unknown flux function \"" + flux + "\""); } }
public static void Toro5AllButRusanovTest(ConvectiveFluxTypes flux) { CheckErrorThresholds( Toro5Test(flux), Tuple.Create("L2ErrorDensity", 5.1e-1), Tuple.Create("L2ErrorVelocity", 1.4e-0), Tuple.Create("L2ErrorPressure", 2.9e+1)); }
public static void Toro2AllButRusanovTest(ConvectiveFluxTypes flux) { CheckErrorThresholds( Toro2Test(flux), Tuple.Create("L2ErrorDensity", 3.2e-2), Tuple.Create("L2ErrorVelocity", 7.1e-2), Tuple.Create("L2ErrorPressure", 1.8e-2)); }
public static void Toro1AllButRusanovTest(ConvectiveFluxTypes flux) { CheckErrorThresholds( Toro1Test(flux), Tuple.Create("L2ErrorDensity", 2.5e-2), Tuple.Create("L2ErrorVelocity", 7.9e-2), Tuple.Create("L2ErrorPressure", 2.0e-2)); }
//public static void Main(string[] args) { // SetUp(); // Toro1AllButRusanovTest(ConvectiveFluxTypes.Godunov); //} /// <summary> /// Toro 2009, p. 334, case 1 /// </summary> /// <param name="flux"></param> /// <returns></returns> private static Dictionary <string, object> Toro1Test(ConvectiveFluxTypes flux) { CNSControl c = GetShockTubeControlTemplate( convectiveFlux: flux, densityLeft: 1.0, velocityLeft: 0.75, pressureLeft: 1.0, densityRight: 0.125, velocityRight: 0.0, pressureRight: 0.1, discontinuityPosition: 0.3); c.ProjectName = "Shock tube, Toro case 1"; c.ProjectDescription = "Toro 2009, p. 334, case 1"; c.Endtime = 0.2; var solver = new Program(); solver.Init(c); solver.RunSolverMode(); return(solver.QueryHandler.QueryResults); }
/// <summary> /// Toro 2009, p. 334, case 4 /// </summary> private static Dictionary <string, object> Toro4Test(ConvectiveFluxTypes flux) { CNSControl c = GetShockTubeControlTemplate( convectiveFlux: flux, densityLeft: 5.99924, velocityLeft: 19.5975, pressureLeft: 460.894, densityRight: 5.99242, velocityRight: -6.19633, pressureRight: 46.0950, discontinuityPosition: 0.4); c.ProjectName = "Shock tube, Toro case 4"; c.ProjectDescription = "Toro 2009, p. 334, case 4"; c.Endtime = 0.035; var solver = new Program(); solver.Init(c); solver.RunSolverMode(); return(solver.QueryHandler.QueryResults); }
public static IBMControl PistonControl(int dgDegree, int rkDegree, ConvectiveFluxTypes convectiveFlux, TimesteppingStrategies timeSteppingStrategy, double agglomerationThreshold) { double pistonVelocity = 1.0; double initialLevelSetPosition = 0.1; //double initialLevelSetPosition = 0.5; IBMControl c = new IBMControl(); c.DbPath = null; c.savetodb = false; c.ProjectName = "Piston"; c.ProjectDescription = "Vertical moving at flow velocity through constant flow field"; c.DomainType = DomainTypes.MovingImmersedBoundary; c.ActiveOperators = Operators.Convection; c.ConvectiveFluxType = convectiveFlux; c.EquationOfState = IdealGas.Air; c.MachNumber = 1.0 / Math.Sqrt(c.EquationOfState.HeatCapacityRatio); c.TimesteppingStrategy = timeSteppingStrategy; c.ExplicitScheme = ExplicitSchemes.RungeKutta; c.ExplicitOrder = rkDegree; c.AddVariable(Variables.Density, dgDegree); c.AddVariable(Variables.Momentum.xComponent, dgDegree); c.AddVariable(Variables.Momentum.yComponent, dgDegree); c.AddVariable(Variables.Energy, dgDegree); c.AddVariable(IBMVariables.LevelSet, 1); c.GridFunc = delegate { double[] xNodes = GenericBlas.Linspace(0.0, 2.0, 4); double[] yNodes = GenericBlas.Linspace(-1.0, 1.0, 4); var grid = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: false, periodicY: true); grid.EdgeTagNames.Add(1, "adiabaticSlipWall"); grid.EdgeTagNames.Add(2, "supersonicInlet"); grid.DefineEdgeTags(X => 2); return(grid); }; c.CutCellQuadratureType = XQuadFactoryHelper.MomentFittingVariants.Classic; c.LevelSetQuadratureOrder = 10; c.LevelSetBoundaryTag = "adiabaticSlipWall"; c.AgglomerationThreshold = agglomerationThreshold; c.InitialValues_Evaluators.Add(Variables.Density, X => 1.0); c.InitialValues_Evaluators.Add(Variables.Velocity.xComponent, X => pistonVelocity); c.InitialValues_Evaluators.Add(Variables.Velocity.yComponent, X => 0.0); c.InitialValues_Evaluators.Add(Variables.Pressure, X => 1.0); c.LevelSetFunction = delegate(double[] X, double time) { double newLevelSetPosition = initialLevelSetPosition + pistonVelocity * time; return(X[0] - newLevelSetPosition); }; c.LevelSetVelocity = (X, t) => new Vector(pistonVelocity, 0.0); c.AddBoundaryValue("adiabaticSlipWall", Variables.Velocity.xComponent, X => pistonVelocity); c.AddBoundaryValue("adiabaticSlipWall", Variables.Velocity.yComponent, X => 0.0); c.AddBoundaryValue("supersonicInlet", Variables.Density, X => 1.0); c.AddBoundaryValue("supersonicInlet", Variables.Velocity[0], X => pistonVelocity); c.AddBoundaryValue("supersonicInlet", Variables.Velocity[1], X => 0.0); c.AddBoundaryValue("supersonicInlet", Variables.Pressure, X => 1.0); c.Queries.Add("L2ErrorDensity", IBMQueries.L2Error(Variables.Density, (X, t) => 1.0)); c.Queries.Add("L2ErrorXMomentum", IBMQueries.L2Error(Variables.Momentum.xComponent, (X, t) => 1.0)); c.Queries.Add("L2ErrorYMomentum", IBMQueries.L2Error(Variables.Momentum.yComponent, (X, t) => 0.0)); c.Queries.Add("L2ErrorPressure", IBMQueries.L2Error(state => state.Pressure, (X, t) => 1.0)); c.dtMin = 0.0; c.dtMax = 1.0; c.CFLFraction = 0.1; c.Endtime = 0.75; c.NoOfTimesteps = int.MaxValue; return(c); }
/// <summary> /// Template for all shock tube tests /// </summary> /// <param name="convectiveFlux"></param> /// <param name="densityLeft"></param> /// <param name="velocityLeft"></param> /// <param name="pressureLeft"></param> /// <param name="densityRight"></param> /// <param name="velocityRight"></param> /// <param name="pressureRight"></param> /// <param name="discontinuityPosition"></param> /// <returns></returns> private static CNSControl GetShockTubeControlTemplate(ConvectiveFluxTypes convectiveFlux, double densityLeft, double velocityLeft, double pressureLeft, double densityRight, double velocityRight, double pressureRight, double discontinuityPosition) { CNSControl c = new CNSControl(); c.DbPath = null; c.savetodb = false; c.ActiveOperators = Operators.Convection; c.ConvectiveFluxType = convectiveFlux; c.EquationOfState = IdealGas.Air; c.MachNumber = 1.0 / Math.Sqrt(c.EquationOfState.HeatCapacityRatio); c.ExplicitScheme = ExplicitSchemes.RungeKutta; c.ExplicitOrder = 1; int dgDegree = 0; c.AddVariable(Variables.Density, dgDegree); c.AddVariable(Variables.Momentum.xComponent, dgDegree); c.AddVariable(Variables.Energy, dgDegree); c.AddVariable(Variables.Pressure, dgDegree); c.AddVariable(Variables.Velocity.xComponent, dgDegree); c.GridFunc = delegate { double[] xNodes = GenericBlas.Linspace(0.0, 1.0, 201); var grid = Grid1D.LineGrid(xNodes, false); grid.EdgeTagNames.Add(1, "supersonicOutlet"); grid.DefineEdgeTags(X => 1); return(grid); }; // Take inner values everywhere c.AddBoundaryCondition("supersonicOutlet"); Material material = new Material(c); StateVector stateLeft = StateVector.FromPrimitiveQuantities( material, densityLeft, new Vector3D(velocityLeft, 0.0, 0.0), pressureLeft); StateVector stateRight = StateVector.FromPrimitiveQuantities( material, densityRight, new Vector3D(velocityRight, 0.0, 0.0), pressureRight); c.InitialValues_Evaluators.Add( Variables.Density, X => stateLeft.Density + (stateRight.Density - stateLeft.Density) * (X[0] - discontinuityPosition).Heaviside()); c.InitialValues_Evaluators.Add( Variables.Velocity.xComponent, X => stateLeft.Velocity.x + (stateRight.Velocity.x - stateLeft.Velocity.x) * (X[0] - discontinuityPosition).Heaviside()); c.InitialValues_Evaluators.Add( Variables.Pressure, X => stateLeft.Pressure + (stateRight.Pressure - stateLeft.Pressure) * (X[0] - discontinuityPosition).Heaviside()); var riemannSolver = new ExactRiemannSolver(stateLeft, stateRight, new Vector3D(1.0, 0.0, 0.0)); double pStar, uStar; riemannSolver.GetStarRegionValues(out pStar, out uStar); c.Queries.Add("L2ErrorDensity", QueryLibrary.L2Error( Variables.Density, (X, t) => riemannSolver.GetState(pStar, uStar, X[0] - discontinuityPosition, t).Density)); c.Queries.Add("L2ErrorVelocity", QueryLibrary.L2Error( Variables.Velocity.xComponent, (X, t) => riemannSolver.GetState(pStar, uStar, X[0] - discontinuityPosition, t).Velocity.x)); c.Queries.Add("L2ErrorPressure", QueryLibrary.L2Error( Variables.Pressure, (X, t) => riemannSolver.GetState(pStar, uStar, X[0] - discontinuityPosition, t).Pressure)); c.dtMin = 0.0; c.dtMax = 1.0; c.CFLFraction = 0.5; c.NoOfTimesteps = int.MaxValue; c.PrintInterval = 50; return(c); }
/// <summary> /// Template of the control file for all shock tube tests using artificial viscosity /// </summary> /// <param name="convectiveFlux"></param> /// <param name="densityLeft"></param> /// <param name="velocityLeft"></param> /// <param name="pressureLeft"></param> /// <param name="densityRight"></param> /// <param name="velocityRight"></param> /// <param name="pressureRight"></param> /// <param name="discontinuityPosition"></param> /// <param name="explicitScheme"></param> /// <param name="explicitOrder"></param> /// <param name="numOfClusters"></param> /// <returns></returns> private static CNSControl GetArtificialViscosityShockTubeControlTemplate(ConvectiveFluxTypes convectiveFlux, double densityLeft, double velocityLeft, double pressureLeft, double densityRight, double velocityRight, double pressureRight, double discontinuityPosition, ExplicitSchemes explicitScheme, int explicitOrder, int numOfClusters) { CNSControl c = new CNSControl(); c.DbPath = null; c.savetodb = false; //c.DbPath = @"c:\bosss_db\"; //c.savetodb = true; //c.saveperiod = 100; //c.PrintInterval = 100; c.ActiveOperators = Operators.Convection | Operators.ArtificialViscosity; c.ConvectiveFluxType = convectiveFlux; c.EquationOfState = IdealGas.Air; c.MachNumber = 1.0 / Math.Sqrt(c.EquationOfState.HeatCapacityRatio); c.ReynoldsNumber = 1.0; c.PrandtlNumber = 0.71; // Time stepping scheme c.ExplicitScheme = explicitScheme; c.ExplicitOrder = explicitOrder; if (explicitScheme == ExplicitSchemes.LTS) { c.NumberOfSubGrids = numOfClusters; c.ReclusteringInterval = 1; c.FluxCorrection = false; } int dgDegree = 3; int noOfCellsPerDirection = 50; double sensorLimit = 1e-4; double epsilon0 = 1.0; double kappa = 0.5; Variable sensorVariable = Variables.Density; c.ShockSensor = new PerssonSensor(sensorVariable, sensorLimit); c.ArtificialViscosityLaw = new SmoothedHeavisideArtificialViscosityLaw(c.ShockSensor, dgDegree, sensorLimit, epsilon0, kappa); c.AddVariable(Variables.Density, dgDegree); c.AddVariable(Variables.Momentum.xComponent, dgDegree); c.AddVariable(Variables.Energy, dgDegree); c.AddVariable(Variables.Velocity.xComponent, dgDegree); c.AddVariable(Variables.Pressure, dgDegree); c.AddVariable(Variables.Entropy, dgDegree); c.AddVariable(Variables.Viscosity, dgDegree); c.AddVariable(Variables.ArtificialViscosity, 1); //c.AddVariable(Variables.Sensor, dgDegree); c.AddVariable(Variables.LocalMachNumber, dgDegree); if (c.ExplicitScheme.Equals(ExplicitSchemes.LTS)) { c.AddVariable(Variables.LTSClusters, 0); } c.GridFunc = delegate { double[] xNodes = GenericBlas.Linspace(0.0, 1.0, noOfCellsPerDirection + 1); var grid = Grid1D.LineGrid(xNodes, periodic: false); // Boundary conditions grid.EdgeTagNames.Add(1, "AdiabaticSlipWall"); grid.DefineEdgeTags(delegate(double[] _X) { return(1); }); return(grid); }; c.AddBoundaryCondition("AdiabaticSlipWall"); Material material = new Material(c); StateVector stateLeft = StateVector.FromPrimitiveQuantities( material, densityLeft, new Vector3D(velocityLeft, 0.0, 0.0), pressureLeft); StateVector stateRight = StateVector.FromPrimitiveQuantities( material, densityRight, new Vector3D(velocityRight, 0.0, 0.0), pressureRight); c.InitialValues_Evaluators.Add( Variables.Density, X => stateLeft.Density + (stateRight.Density - stateLeft.Density) * (X[0] - discontinuityPosition).Heaviside()); c.InitialValues_Evaluators.Add( Variables.Velocity.xComponent, X => stateLeft.Velocity.x + (stateRight.Velocity.x - stateLeft.Velocity.x) * (X[0] - discontinuityPosition).Heaviside()); c.InitialValues_Evaluators.Add( Variables.Pressure, X => stateLeft.Pressure + (stateRight.Pressure - stateLeft.Pressure) * (X[0] - discontinuityPosition).Heaviside()); var riemannSolver = new ExactRiemannSolver(stateLeft, stateRight, new Vector3D(1.0, 0.0, 0.0)); double pStar, uStar; riemannSolver.GetStarRegionValues(out pStar, out uStar); c.Queries.Add("L2ErrorDensity", QueryLibrary.L2Error( Variables.Density, (X, t) => riemannSolver.GetState(pStar, uStar, X[0] - discontinuityPosition, t).Density)); c.Queries.Add("L2ErrorVelocity", QueryLibrary.L2Error( Variables.Velocity.xComponent, (X, t) => riemannSolver.GetState(pStar, uStar, X[0] - discontinuityPosition, t).Velocity.x)); c.Queries.Add("L2ErrorPressure", QueryLibrary.L2Error( Variables.Pressure, (X, t) => riemannSolver.GetState(pStar, uStar, X[0] - discontinuityPosition, t).Pressure)); c.dtMin = 0.0; c.dtMax = 1.0; c.dtFixed = 1.0e-6; c.Endtime = 5e-04; //c.NoOfTimesteps = 500; c.NoOfTimesteps = int.MaxValue; return(c); }