//private static CommandLineOptions commandLineOptions = new CommandLineOptions() { // delPlt = true, // ImmediatePlotPeriod = 1 //}; //public static void Main(string[] args) { // SetUp(); // ToroTest1(); //} /// <summary> /// Test 1 from Toro 2009, p. 119, table 4.1 using the OptimizedHLLC convective flux. /// The results are compared to the analytical solution that is calculated by /// the ExactRiemannSolver implementation in BoSSS. /// </summary> private static Dictionary <string, object> SetupToroTest1(ExplicitSchemes explicitScheme, int explicitOrder, int numOfClusters) { CNSControl c = GetArtificialViscosityShockTubeControlTemplate( convectiveFlux: ConvectiveFluxTypes.OptimizedHLLC, densityLeft: 1.0, velocityLeft: 0.0, pressureLeft: 1.0, densityRight: 0.125, velocityRight: 0.0, pressureRight: 0.1, discontinuityPosition: 0.5, explicitScheme: explicitScheme, explicitOrder: explicitOrder, numOfClusters: numOfClusters); c.ProjectName = "Artificial viscosity, shock tube, Toro test 1"; c.ProjectDescription = "Toro 2009, p. 129, table 4.1, test 1"; var solver = new Program(); solver.Init(c, commandLineOptions); solver.RunSolverMode(); return(solver.QueryHandler.QueryResults); }
public static void TestRebalancingForDG2WithRK1AndAV_IBM_AggOff() { int dgDegree = 2; ExplicitSchemes explicitScheme = ExplicitSchemes.RungeKutta; int explicitOrder = 1; IBMControl control = ShockTubeToro1WithIBMAndAVTemplate( dgDegree: dgDegree, explicitScheme: explicitScheme, explicitOrder: explicitOrder); control.AgglomerationThreshold = 0.1; // MUST be the same as rebalancing period since LTS scheme MUST // recluster after rebalancing (at least, it makes life much easier) //control.ReclusteringInterval = REBALANCING_PERIOD; //control.NumberOfSubGrids = 3; //control.maxNumOfSubSteps = 10; //control.FluxCorrection = false; Console.WriteLine("TestRebalancingForDG2WithRK1AndAV_IBM_AggOff"); // Threshold is set to 2e1-3, since METIS results for density are worse compared to Hilbert // Could be influenced by the handling of cut-cells along processor boundaries, communication plays // a more important role for non-agglomerated cut-cells in the IBM-case as for non-IBM simulations, etc. // Anyway, this does not seem to be a real problem. CheckRunsProduceSameResults(control, differenceThreshold: 2e-13, hilbert: true); }
public static void TestRebalancingForDG2WithLTS1AndAV_IBM_AggOn() { int dgDegree = 2; ExplicitSchemes explicitScheme = ExplicitSchemes.LTS; int explicitOrder = 1; IBMControl control = ShockTubeToro1WithIBMAndAVTemplate( dgDegree: dgDegree, explicitScheme: explicitScheme, explicitOrder: explicitOrder); control.AgglomerationThreshold = 0.9; control.Endtime = 0.005; //control.Endtime = 0.002; //control.DbPath = @"c:\bosss_db\"; //control.savetodb = true; // MUST be the same as rebalancing period since LTS scheme MUST // recluster after rebalancing (at least, it makes life much easier) control.ReclusteringInterval = REBALANCING_PERIOD; control.NumberOfSubGrids = 2; control.FluxCorrection = false; control.maxNumOfSubSteps = 10; control.forceReclustering = true; Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name); CheckRunsProduceSameResults(control, hilbert: false); }
private static CNSControl ShockTubeToro1WithAVTemplate(int dgDegree, ExplicitSchemes explicitScheme, int explicitOrder, int noOfCells = 50, bool twoD = false) { Variable sensorVariable = CompressibleVariables.Density; double sensorLimit = 1e-3; double epsilon0 = 1.0; double kappa = 0.5; double endTime = 0.01; var c = ShockTubeToro1Template( dgDegree: dgDegree, explicitScheme: explicitScheme, explicitOrder: explicitOrder, twoD: twoD); if (twoD) { c.AddVariable(CNSVariables.ArtificialViscosity, 2); } else { c.AddVariable(CNSVariables.ArtificialViscosity, 1); } c.ActiveOperators |= Operators.ArtificialViscosity; c.CNSShockSensor = new PerssonSensor(sensorVariable, sensorLimit); c.AddVariable(CNSVariables.ShockSensor, 0); c.ArtificialViscosityLaw = new SmoothedHeavisideArtificialViscosityLaw(c.CNSShockSensor, dgDegree, sensorLimit, epsilon0, kappa, lambdaMax: 2); c.Endtime = endTime; return(c); }
public static void TestRebalancingForDG0WithLTS1TwoSubGrids() { int dgDegree = 0; ExplicitSchemes explicitScheme = ExplicitSchemes.LTS; int explicitOrder = 1; int noOfSubgrids = 2; double gridStretching = 1.0; var control = ShockTubeToro1Template( dgDegree: dgDegree, explicitScheme: explicitScheme, explicitOrder: explicitOrder, gridStretching: gridStretching); control.NumberOfSubGrids = noOfSubgrids; // MUST be the same as rebalancing period since LTS scheme MUST // recluster after rebalancing (at least, it makes life much easier) control.ReclusteringInterval = REBALANCING_PERIOD; //control.NoOfTimesteps = 5; //control.dtFixed = 1.5e-3; CheckRunsProduceSameResults(control); }
public static void TestRebalancingForDG0WithLTS1SingleSubGrid() { int dgDegree = 0; ExplicitSchemes explicitScheme = ExplicitSchemes.LTS; int explicitOrder = 1; var control = ShockTubeToro1Template( dgDegree: dgDegree, explicitScheme: explicitScheme, explicitOrder: explicitOrder); CheckRunsProduceSameResults(control); }
public static void TestRebalancingForDG0WithAB1() { int dgDegree = 0; ExplicitSchemes explicitScheme = ExplicitSchemes.AdamsBashforth; int explicitOrder = 1; var control = ShockTubeToro1Template( dgDegree: dgDegree, explicitScheme: explicitScheme, explicitOrder: explicitOrder); CheckRunsProduceSameResults(control); }
public static void TestRebalancingForDG2WithRK1AndAV() { int dgDegree = 2; ExplicitSchemes explicitScheme = ExplicitSchemes.RungeKutta; int explicitOrder = 1; var control = ShockTubeToro1WithAVTemplate( dgDegree: dgDegree, explicitScheme: explicitScheme, explicitOrder: explicitOrder); CheckRunsProduceSameResults(control); }
public static void TestRebalancingForDG2WithRK1AndAV() { int dgDegree = 2; ExplicitSchemes explicitScheme = ExplicitSchemes.RungeKutta; int explicitOrder = 1; var control = ShockTubeToro1WithAVTemplate( dgDegree: dgDegree, explicitScheme: explicitScheme, explicitOrder: explicitOrder); Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name); CheckRunsProduceSameResults(control); }
public static void TestRebalancingForDG0WithAB1() { int dgDegree = 0; ExplicitSchemes explicitScheme = ExplicitSchemes.AdamsBashforth; int explicitOrder = 1; var control = ShockTubeToro1Template( dgDegree: dgDegree, explicitScheme: explicitScheme, explicitOrder: explicitOrder); Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name); CheckRunsProduceSameResults(control); }
/// <summary> /// There is an problem for AV and IBMSplitRungeKutta. /// This test currently fails because of some unknown reason. /// - IBMSplitRungeKutta should work, as it is used, e.g. in <see cref="TestRebalancingForDG0WithRK1_IBM_AggOff"/> /// - RaiseOnBeforeComputeChangeRate should be called in all IBM Runge-Kutta time steppers /// </summary> //[Test] public static void TestRebalancingForDG2WithRK1AndAV_IBM_AggOn() { int dgDegree = 2; ExplicitSchemes explicitScheme = ExplicitSchemes.RungeKutta; int explicitOrder = 1; IBMControl control = ShockTubeToro1WithIBMAndAVTemplate( dgDegree: dgDegree, explicitScheme: explicitScheme, explicitOrder: explicitOrder); control.AgglomerationThreshold = 0.9; control.Endtime = 0.0005; Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name); CheckRunsProduceSameResults(control); }
public static void TestRebalancingForDG2WithLTS1TwoSubGridsAndAV() { int dgDegree = 2; ExplicitSchemes explicitScheme = ExplicitSchemes.LTS; int explicitOrder = 1; int noOfSubgrids = 2; var control = ShockTubeToro1WithAVTemplate( dgDegree: dgDegree, explicitScheme: explicitScheme, explicitOrder: explicitOrder); control.NumberOfSubGrids = noOfSubgrids; // MUST be the same as rebalancing period since LTS scheme MUST // recluster after rebalancing (at least, it makes life much easier) control.ReclusteringInterval = REBALANCING_PERIOD; Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name); CheckRunsProduceSameResults(control, hilbert: false); }
public static void TestRebalancingForDG2WithRK1AndAV_IBM_AggOn() { int dgDegree = 2; ExplicitSchemes explicitScheme = ExplicitSchemes.RungeKutta; int explicitOrder = 1; IBMControl control = ShockTubeToro1WithIBMAndAVTemplate( dgDegree: dgDegree, explicitScheme: explicitScheme, explicitOrder: explicitOrder); control.AgglomerationThreshold = 0.9; // MUST be the same as rebalancing period since LTS scheme MUST // recluster after rebalancing (at least, it makes life much easier) //control.ReclusteringInterval = REBALANCING_PERIOD; //control.NumberOfSubGrids = 3; //control.maxNumOfSubSteps = 10; //control.FluxCorrection = false; Console.WriteLine("TestRebalancingForDG2WithRK1AndAV_IBM_AggOn"); CheckRunsProduceSameResults(control, hilbert: true); }
/// <summary> /// Creates the appropriate time-stepper for a given /// <paramref name="timeStepperType"/> /// </summary> /// <param name="timeStepperType"> /// The type of the time-stepper (e.g., Runge-Kutta) to be created /// </param> /// <param name="control"> /// Configuration options /// </param> /// <param name="equationSystem"> /// The equation system to be solved /// </param> /// <param name="fieldSet"> /// Fields affected by the time-stepper /// </param> /// <param name="parameterMap"> /// Fields serving as parameter for the time-stepper. /// </param> /// <param name="speciesMap"> /// Mapping of different species inside the domain /// </param> /// <param name="program"></param> /// <returns> /// Depending on <paramref name="timeStepperType"/>, an appropriate /// implementation of <see cref="ITimeStepper"/>. /// </returns> /// <remarks> /// Currently limiting is not supported for Adams-Bashforth methods /// </remarks> public static ITimeStepper Instantiate <T>( this ExplicitSchemes timeStepperType, CNSControl control, OperatorFactory equationSystem, CNSFieldSet fieldSet, CoordinateMapping parameterMap, ISpeciesMap speciesMap, IProgram <T> program) where T : CNSControl, new() { CoordinateMapping variableMap = new CoordinateMapping(fieldSet.ConservativeVariables); IBMControl ibmControl = control as IBMControl; IBMOperatorFactory ibmFactory = equationSystem as IBMOperatorFactory; if (control.DomainType != DomainTypes.Standard && (ibmFactory == null || ibmControl == null)) { throw new Exception(); } ITimeStepper timeStepper; switch (timeStepperType) { case ExplicitSchemes.RungeKutta when control.DomainType == DomainTypes.Standard: timeStepper = new RungeKutta( RungeKutta.GetDefaultScheme(control.ExplicitOrder), equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet), variableMap, parameterMap, equationSystem.GetJoinedOperator().CFLConstraints); break; case ExplicitSchemes.RungeKutta: timeStepper = ibmControl.TimesteppingStrategy.CreateRungeKuttaTimeStepper( ibmControl, equationSystem, fieldSet, parameterMap, speciesMap, equationSystem.GetJoinedOperator().CFLConstraints); break; case ExplicitSchemes.AdamsBashforth when control.DomainType == DomainTypes.Standard: timeStepper = new AdamsBashforth( equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet), variableMap, parameterMap, control.ExplicitOrder, equationSystem.GetJoinedOperator().CFLConstraints); break; case ExplicitSchemes.AdamsBashforth: timeStepper = new IBMAdamsBashforth( ibmFactory.GetJoinedOperator().ToSpatialOperator(fieldSet), ibmFactory.GetImmersedBoundaryOperator().ToSpatialOperator(fieldSet), variableMap, parameterMap, speciesMap, ibmControl, equationSystem.GetJoinedOperator().CFLConstraints); break; case ExplicitSchemes.LTS when control.DomainType == DomainTypes.Standard: timeStepper = new AdamsBashforthLTS( equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet), variableMap, parameterMap, control.ExplicitOrder, control.NumberOfSubGrids, equationSystem.GetJoinedOperator().CFLConstraints, reclusteringInterval: control.ReclusteringInterval, fluxCorrection: control.FluxCorrection, saveToDBCallback: program.SaveToDatabase, maxNumOfSubSteps: control.maxNumOfSubSteps, forceReclustering: control.forceReclustering, logging: control.WriteLTSLog, consoleOutput: control.WriteLTSConsoleOutput); break; case ExplicitSchemes.LTS: timeStepper = new IBMAdamsBashforthLTS( equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet), ibmFactory.GetImmersedBoundaryOperator().ToSpatialOperator(fieldSet), variableMap, parameterMap, speciesMap, ibmControl, equationSystem.GetJoinedOperator().CFLConstraints, reclusteringInterval: control.ReclusteringInterval, fluxCorrection: control.FluxCorrection, maxNumOfSubSteps: control.maxNumOfSubSteps, forceReclustering: control.forceReclustering, logging: control.WriteLTSLog, consoleOutput: control.WriteLTSConsoleOutput); break; case ExplicitSchemes.Rock4 when control.DomainType == DomainTypes.Standard: timeStepper = new ROCK4(equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet), new CoordinateVector(variableMap), null); break; case ExplicitSchemes.SSP54 when control.DomainType == DomainTypes.Standard: timeStepper = new RungeKutta( RungeKuttaScheme.SSP54, equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet), variableMap, parameterMap, equationSystem.GetJoinedOperator().CFLConstraints); break; case ExplicitSchemes.RKC84 when control.DomainType == DomainTypes.Standard: timeStepper = new RungeKutta( RungeKuttaScheme.RKC84, equationSystem.GetJoinedOperator().ToSpatialOperator(fieldSet), variableMap, parameterMap, equationSystem.GetJoinedOperator().CFLConstraints); break; case ExplicitSchemes.None: throw new System.ArgumentException("Cannot instantiate empty scheme"); default: throw new NotImplementedException(String.Format( "Explicit time stepper type '{0}' not implemented for domain type '{1}'", timeStepperType, control.DomainType)); } // Make sure shock sensor is updated before every flux evaluation if (control.CNSShockSensor != null) { ExplicitEuler explicitEulerBasedTimestepper = timeStepper as ExplicitEuler; if (explicitEulerBasedTimestepper == null) { throw new Exception(String.Format( "Shock-capturing currently not implemented for time-steppers of type '{0}'", timeStepperType)); } explicitEulerBasedTimestepper.OnBeforeComputeChangeRate += delegate(double absTime, double relTime) { // Note: Only shock sensor is updated, _NOT_ the corresponding variable program.Control.CNSShockSensor.UpdateSensorValues( program.WorkingSet.AllFields, program.SpeciesMap, explicitEulerBasedTimestepper.SubGrid.VolumeMask); // Note: When being called, artificial viscosity is updated in the _ENTIRE_ (fluid) domain var avField = program.WorkingSet.DerivedFields[CNSVariables.ArtificialViscosity]; CNSVariables.ArtificialViscosity.UpdateFunction(avField, program.SpeciesMap.SubGrid.VolumeMask, program); // Test //double sensorNorm = program.WorkingSet.DerivedFields[CNSVariables.ShockSensor].L2Norm(); //double avNorm = program.WorkingSet.DerivedFields[CNSVariables.ArtificialViscosity].L2Norm(); //Console.WriteLine("\r\nThis is OnBeforeComputeChangeRate"); //Console.WriteLine("SensorNeu: {0}", sensorNorm); //Console.WriteLine("AVNeu: {0}", avNorm); }; } // Make sure limiter is applied after each modification of conservative variables if (control.Limiter != null) { ExplicitEuler explicitEulerBasedTimestepper = timeStepper as ExplicitEuler; if (explicitEulerBasedTimestepper == null) { throw new Exception(String.Format( "Limiting currently not implemented for time-steppers of type '{0}~", timeStepperType)); } explicitEulerBasedTimestepper.OnAfterFieldUpdate += (t, f) => control.Limiter.LimitFieldValues(program.WorkingSet.ConservativeVariables, program.WorkingSet.DerivedFields.Values); } return(timeStepper); }
private static IBMControl ShockTubeToro1WithIBMAndAVTemplate(int dgDegree, ExplicitSchemes explicitScheme, int explicitOrder, int noOfCellsX = 50, int noOfCellsY = 10, bool AV = true) { IBMControl c = new IBMControl(); c.DbPath = null; //c.DbPath = @"c:\bosss_db\"; c.savetodb = false; c.saveperiod = 1; c.PrintInterval = 1; double xMin = 0; double xMax = 1; double yMin = 0; double yMax = 1; c.DomainType = DomainTypes.StaticImmersedBoundary; c.LevelSetFunction = delegate(double[] X, double t) { return(X[1] - 0.16); }; c.LevelSetBoundaryTag = "AdiabaticSlipWall"; c.CutCellQuadratureType = XQuadFactoryHelper.MomentFittingVariants.OneStepGaussAndStokes; c.LevelSetQuadratureOrder = 6; c.AgglomerationThreshold = 0.3; c.AddVariable(IBMVariables.LevelSet, 1); //c.AddVariable(IBMVariables.FluidCells, 1); //c.AddVariable(IBMVariables.FluidCellsWithoutSourceCells, 1); //c.AddVariable(IBMVariables.CutCells, 1); //c.AddVariable(IBMVariables.CutCellsWithoutSourceCells, 1); //c.AddVariable(IBMVariables.SourceCells, 1); if (AV) { c.ActiveOperators = Operators.Convection | Operators.ArtificialViscosity; } else { c.ActiveOperators = Operators.Convection; } c.ConvectiveFluxType = ConvectiveFluxTypes.OptimizedHLLC; // Shock-capturing double sensorLimit = 1e-3; double epsilon0 = 1.0; double kappa = 0.5; if (AV) { Variable sensorVariable = CompressibleVariables.Density; c.CNSShockSensor = new PerssonSensor(sensorVariable, sensorLimit); c.AddVariable(CNSVariables.ShockSensor, 0); c.ArtificialViscosityLaw = new SmoothedHeavisideArtificialViscosityLaw(c.CNSShockSensor, dgDegree, sensorLimit, epsilon0, kappa, lambdaMax: 2); } c.ExplicitScheme = explicitScheme; c.ExplicitOrder = explicitOrder; c.EquationOfState = IdealGas.Air; c.MachNumber = 1.0 / Math.Sqrt(c.EquationOfState.HeatCapacityRatio); c.ReynoldsNumber = 1.0; c.PrandtlNumber = 0.71; c.AddVariable(CompressibleVariables.Density, dgDegree); c.AddVariable(CompressibleVariables.Momentum.xComponent, dgDegree); c.AddVariable(CompressibleVariables.Momentum.yComponent, dgDegree); c.AddVariable(CompressibleVariables.Energy, dgDegree); c.AddVariable(CNSVariables.Velocity.xComponent, dgDegree); c.AddVariable(CNSVariables.Velocity.yComponent, dgDegree); c.AddVariable(CNSVariables.Pressure, dgDegree); c.AddVariable(CNSVariables.Rank, 0); if (AV) { c.AddVariable(CNSVariables.ArtificialViscosity, 2); c.AddVariable(CNSVariables.CFLArtificialViscosity, 0); } c.AddVariable(CNSVariables.CFL, 0); c.AddVariable(CNSVariables.CFLConvective, 0); if (c.ExplicitScheme.Equals(ExplicitSchemes.LTS)) { c.AddVariable(CNSVariables.LTSClusters, 0); } c.GridFunc = delegate { double[] xNodes = GenericBlas.Linspace(xMin, xMax, noOfCellsX + 1); double[] yNodes = GenericBlas.Linspace(yMin, yMax, noOfCellsY + 1); var grid = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: false, periodicY: false); // Boundary conditions grid.EdgeTagNames.Add(1, "AdiabaticSlipWall"); grid.DefineEdgeTags(delegate(double[] _X) { return(1); }); return(grid); }; c.AddBoundaryValue("AdiabaticSlipWall"); // Normal vector of initial shock Vector normalVector = new Vector(1, 0); // Direction vector of initial shock Vector r = new Vector(normalVector.y, -normalVector.x); r.Normalize(); // Distance from a point X to the initial shock double[] p = new double[] { 0.5, 0.0 }; double cellSize = Math.Min((xMax - xMin) / noOfCellsX, (yMax - yMin) / noOfCellsY); Func <double, double> SmoothJump = delegate(double distance) { // smoothing should be in the range of h/p double maxDistance = 4.0 * cellSize / Math.Max(dgDegree, 1); return((Math.Tanh(distance / maxDistance) + 1.0) * 0.5); }; Func <double, double> Jump = (x => x <= 0.5 ? 0 : 1); // Initial conditions double densityLeft = 1.0; double densityRight = 0.125; double pressureLeft = 1.0; double pressureRight = 0.1; //c.InitialValues_Evaluators.Add(Variables.Density, X => densityLeft - SmoothJump(DistanceFromPointToLine(X, p, r)) * (densityLeft - densityRight)); //c.InitialValues_Evaluators.Add(CNSVariables.Pressure, X => pressureLeft - SmoothJump(DistanceFromPointToLine(X, p, r)) * (pressureLeft - pressureRight)); c.InitialValues_Evaluators.Add(CompressibleVariables.Density, X => densityLeft - Jump(X[0]) * (densityLeft - densityRight)); c.InitialValues_Evaluators.Add(CNSVariables.Pressure, X => pressureLeft - Jump(X[0]) * (pressureLeft - pressureRight)); c.InitialValues_Evaluators.Add(CNSVariables.Velocity.xComponent, X => 0.0); c.InitialValues_Evaluators.Add(CNSVariables.Velocity.yComponent, X => 0.0); // Time config c.dtMin = 0.0; c.dtMax = 1.0; c.CFLFraction = 0.1; c.Endtime = 0.001; c.NoOfTimesteps = int.MaxValue; c.ProjectName = "Shock tube"; c.SessionName = String.Format("IBM shock tube, p={0}, {1}x{2} cells, agg={3}, s0={4:0.0E-00}, CFLFrac={5}, ALTS {6}/{7}/{8}({9}), Part={10}/{11}({12})", dgDegree, noOfCellsX, noOfCellsY, c.AgglomerationThreshold, sensorLimit, c.CFLFraction, c.ExplicitOrder, c.NumberOfSubGrids, c.ReclusteringInterval, c.maxNumOfSubSteps, c.GridPartType.ToString(), c.DynamicLoadBalancing_Period, c.DynamicLoadBalancing_ImbalanceThreshold); return(c); }
private static CNSControl ShockTubeToro1Template(int dgDegree, ExplicitSchemes explicitScheme, int explicitOrder, int noOfCells = 50, double gridStretching = 0.0, bool twoD = false) { double densityLeft = 1.0; double velocityLeft = 0.0; double pressureLeft = 1.0; double densityRight = 0.125; double velocityRight = 0.0; double pressureRight = 0.1; double discontinuityPosition = 0.5; CNSControl c = new CNSControl(); c.DbPath = null; //c.DbPath = @"c:\bosss_db\"; c.savetodb = false; c.ActiveOperators = Operators.Convection; c.ConvectiveFluxType = ConvectiveFluxTypes.OptimizedHLLC; c.EquationOfState = IdealGas.Air; c.MachNumber = 1.0 / Math.Sqrt(c.EquationOfState.HeatCapacityRatio); c.ReynoldsNumber = 1.0; c.PrandtlNumber = 0.71; c.ExplicitScheme = explicitScheme; c.ExplicitOrder = explicitOrder; c.AddVariable(CompressibleVariables.Density, dgDegree); c.AddVariable(CompressibleVariables.Momentum.xComponent, dgDegree); c.AddVariable(CompressibleVariables.Energy, dgDegree); c.AddVariable(CNSVariables.Velocity.xComponent, dgDegree); c.AddVariable(CNSVariables.Pressure, dgDegree); c.AddVariable(CNSVariables.Rank, 0); c.GridFunc = delegate { double xMin = 0.0; double xMax = 1.0; double yMin = 0.0; double yMax = 1.0; double[] xNodes; double[] yNodes; if (gridStretching > 0.0) { xNodes = Grid1D.TanhSpacing(xMin, xMax, noOfCells + 1, gridStretching, true); yNodes = Grid1D.TanhSpacing(yMin, yMax, 1 + 1, gridStretching, true); } else { xNodes = GenericBlas.Linspace(xMin, xMax, noOfCells + 1); yNodes = GenericBlas.Linspace(yMin, yMax, 1 + 1); } GridCommons grid; if (twoD) { grid = Grid2D.Cartesian2DGrid(xNodes, yNodes, periodicX: false, periodicY: false); } else { grid = Grid1D.LineGrid(xNodes, periodic: false); } // Boundary conditions grid.EdgeTagNames.Add(1, "AdiabaticSlipWall"); grid.DefineEdgeTags(delegate(double[] _X) { return(1); }); return(grid); }; c.AddBoundaryValue("AdiabaticSlipWall"); Material material = c.GetMaterial(); StateVector stateLeft = StateVector.FromPrimitiveQuantities( material, densityLeft, new Vector(velocityLeft, 0.0, 0.0), pressureLeft); StateVector stateRight = StateVector.FromPrimitiveQuantities( material, densityRight, new Vector(velocityRight, 0.0, 0.0), pressureRight); c.InitialValues_Evaluators.Add( CompressibleVariables.Density, X => stateLeft.Density + (stateRight.Density - stateLeft.Density) * (X[0] - discontinuityPosition).Heaviside()); c.InitialValues_Evaluators.Add( CNSVariables.Velocity.xComponent, X => stateLeft.Velocity.x + (stateRight.Velocity.x - stateLeft.Velocity.x) * (X[0] - discontinuityPosition).Heaviside()); c.InitialValues_Evaluators.Add( CNSVariables.Pressure, X => stateLeft.Pressure + (stateRight.Pressure - stateLeft.Pressure) * (X[0] - discontinuityPosition).Heaviside()); if (twoD) { c.InitialValues_Evaluators.Add(CNSVariables.Velocity.yComponent, X => 0); } if (!twoD) { var riemannSolver = new ExactRiemannSolver(stateLeft, stateRight, new Vector(1.0, 0.0, 0.0)); riemannSolver.GetStarRegionValues(out double pStar, out double uStar); c.Queries.Add("L2ErrorDensity", QueryLibrary.L2Error( CompressibleVariables.Density, (X, t) => riemannSolver.GetState(pStar, uStar, X[0] - discontinuityPosition, t).Density)); c.Queries.Add("L2ErrorVelocity", QueryLibrary.L2Error( CNSVariables.Velocity.xComponent, (X, t) => riemannSolver.GetState(pStar, uStar, X[0] - discontinuityPosition, t).Velocity.x)); c.Queries.Add("L2ErrorPressure", QueryLibrary.L2Error( CNSVariables.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.CFLFraction = 0.1; c.Endtime = 0.2; c.NoOfTimesteps = int.MaxValue; // Use METIS since ParMETIS is not installed on build server c.GridPartType = GridPartType.METIS; 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); }