public static IBMControl IBMNACA0012(int MeshPara, int dgDegree, double CFL, double agglomeration, double alpha) { IBMControl c = new IBMControl(); c.savetodb = true; // Solver Settings c.dtMin = 0.0; c.dtMax = 1.0; c.Endtime = 1000.0; c.CFLFraction = CFL; c.NoOfTimesteps = 200000; c.PrintInterval = 10; c.ResidualInterval = 100; c.ResidualLoggerType = ResidualLoggerTypes.ChangeRate | ResidualLoggerTypes.Query; c.ResidualBasedTerminationCriteria.Add("changeRate_L2_abs_rhoE", 1E-8); //IBM Settings c.LevelSetBoundaryTag = "adiabaticSlipWall"; c.LevelSetQuadratureOrder = 2 * dgDegree + 2; c.AgglomerationThreshold = agglomeration; // NEXT STEP: SET THIS BOOL TO FALSE AND JUST USE IN POSITIVE SUB_VOLUME; // THEN TRY BOUNDING BOX APPROACH? // WHY THE HELL DOES THIS CONFIGURATION FAIL!??!?!?!? c.CutCellQuadratureType = XQuadFactoryHelper.MomentFittingVariants.Classic; c.SurfaceHMF_ProjectNodesToLevelSet = false; c.SurfaceHMF_RestrictNodes = true; c.SurfaceHMF_UseGaussNodes = false; c.VolumeHMF_NodeCountSafetyFactor = 3.0; c.VolumeHMF_RestrictNodes = true; c.VolumeHMF_UseGaussNodes = false; //Guid restart = new Guid("cd061fe3-3215-483a-8790-f6fd686d6676"); //c.RestartInfo = new Tuple<Guid, BoSSS.Foundation.IO.TimestepNumber>(restart, -1); // Session Settings c.DbPath = @"\\fdyprime\userspace\kraemer-eis\FDY-Cluster\dbe_NACA\"; //c.DbPath = @"C:\bosss_dbv2\NACA0012"; c.savetodb = true; c.saveperiod = 10000; c.ProjectName = "MeshPara:" + MeshPara + "_CFL=" + c.CFLFraction + "_p=" + dgDegree + "_agg=" + c.AgglomerationThreshold + "_alpha=" + alpha + "_HMF=" + c.CutCellQuadratureType; c.ProjectDescription = "NACA0012 Steady Test with Ma=0.5"; c.Tags.Add("NACA0012"); c.Tags.Add("IBM Test"); c.Tags.Add("steady"); // Solver Type c.DomainType = DomainTypes.StaticImmersedBoundary; c.ActiveOperators = Operators.Convection; c.ConvectiveFluxType = ConvectiveFluxTypes.OptimizedHLLC; // Time-Stepping Settings c.ExplicitScheme = ExplicitSchemes.RungeKutta; c.ExplicitOrder = 1; //Material Settings c.EquationOfState = IdealGas.Air; // Primary Variables 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, 8); // Refined Region double xBegin = -0.012; double xEnd = 1.01; c.GridFunc = delegate { int chords = 100; int xleft = -chords; int xRight = chords; int yBottom = -chords; int yTop = chords; double spacingFactor = 3.95; double[] xnodes1 = Grid1D.TanhSpacing(xleft, xBegin, MeshPara + 1, spacingFactor, false); double[] xnodes2 = Grid1D.TanhSpacing_DoubleSided(xBegin, xEnd, MeshPara + 1, 2.0); double[] xnodes3 = Grid1D.TanhSpacing(xEnd, xRight, MeshPara + 1, spacingFactor, true); double[] xComplete = new double[xnodes1.Length + xnodes2.Length + xnodes3.Length - 2]; for (int i = 0; i < xnodes1.Length; i++) { xComplete[i] = xnodes1[i]; } for (int i = 1; i < xnodes2.Length; i++) { xComplete[i + xnodes1.Length - 1] = xnodes2[i]; } for (int i = 1; i < xnodes3.Length; i++) { xComplete[i + xnodes1.Length + xnodes2.Length - 2] = xnodes3[i]; } double yrefinedTop = 0.2; double yrefinedBottom = -0.2; double[] ynodes1 = Grid1D.TanhSpacing(yBottom, yrefinedBottom, MeshPara + 1, spacingFactor, false); double[] ynodes2 = GenericBlas.Linspace(yrefinedBottom, yrefinedTop, (int)(0.75 * MeshPara) + 1); double[] ynodes3 = Grid1D.TanhSpacing(yrefinedTop, yTop, MeshPara + 1, spacingFactor, true); double[] yComplete = new double[ynodes1.Length + ynodes2.Length + ynodes3.Length - 2]; for (int i = 0; i < ynodes1.Length; i++) { yComplete[i] = ynodes1[i]; } for (int i = 1; i < ynodes2.Length; i++) { yComplete[i + ynodes1.Length - 1] = ynodes2[i]; } for (int i = 1; i < ynodes3.Length; i++) { yComplete[i + ynodes1.Length + ynodes2.Length - 2] = ynodes3[i]; } int numOfCellsX = (xRight - xleft) * MeshPara; int numOfCellsY = (yTop - yBottom) * MeshPara; GridCommons grid = Grid2D.Cartesian2DGrid( xComplete, yComplete ); grid.EdgeTagNames.Add(1, "supersonicinlet"); grid.DefineEdgeTags(x => 1); grid.Name = "[" + xleft + "," + xRight + "]x[" + yBottom + "," + yTop + "]_Cells:(" + (xComplete.Length - 1) + "x" + (yComplete.Length - 1) + ")"; return(grid); }; // Functions Func <double[], double, double> rho = (X, t) => 1.0; Func <double[], double, double> u0 = (X, t) => 1.0; Func <double[], double, double> u1 = (X, t) => 0.0; Func <double[], double, double> pressure = (X, t) => 2.8571428571428; Func <double[], double> test = X => 1 - 0.05 * 0.4 / 1.4 * Math.Pow(Math.Exp(1 - X[0] * X[0] - X[1] * X[1]), (1 / 0.4)); Func <double[], double, double> levelSet = delegate(double[] X, double t) { double value = 0.0; double radian = alpha * Math.PI / 180; double xRotated = 1 + Math.Cos(radian) * (X[0] - 1) - Math.Sin(radian) * (X[1]); double yRotated = Math.Sin(radian) * (X[0] - 1) + Math.Cos(radian) * (X[1]); double a = 0.6; //double b = 0.2969; double c1 = 0.126; double d = 0.3516; double e = 0.2843; double f = 0.1036; if (yRotated >= 0.0 || (X[0] > 0.562875 && X[1] > 0)) { //if (yRotated >= 0.0 ){ value = Math.Pow((yRotated + a * (c1 * xRotated + d * Math.Pow(xRotated, 2) - e * Math.Pow(xRotated, 3) + f * Math.Pow(xRotated, 4))), 2) - 0.0317338596 * xRotated; } else { value = Math.Pow((-yRotated + a * (c1 * xRotated + d * Math.Pow(xRotated, 2) - e * Math.Pow(xRotated, 3) + f * Math.Pow(xRotated, 4))), 2) - 0.0317338596 * xRotated; } //value = yRotated - Math.Tan(radian)*xRotated; return(value); }; c.LevelSetFunction = levelSet; //Initial Values c.InitialValues_Evaluators.Add(Variables.Density, X => rho(X, 0.0)); c.InitialValues_Evaluators.Add(Variables.Velocity.xComponent, X => u0(X, 0.0)); c.InitialValues_Evaluators.Add(Variables.Velocity.yComponent, X => u1(X, 0.0)); c.InitialValues_Evaluators.Add(Variables.Pressure, X => pressure(X, 0.0)); //BoundaryConditions c.AddBoundaryCondition("adiabaticSlipWall"); c.AddBoundaryCondition("supersonicInlet", Variables.Density, rho); c.AddBoundaryCondition("supersonicInlet", Variables.Velocity.xComponent, u0); c.AddBoundaryCondition("supersonicInlet", Variables.Velocity.yComponent, u1); c.AddBoundaryCondition("supersonicInlet", Variables.Pressure, pressure); // Queries c.Queries.Add("L2ErrorEntropy", IBMQueries.L2Error(state => state.Entropy, (X, t) => 2.8571428571428)); c.Queries.Add("IBMDragForce", IBMQueries.IBMDragForce()); c.Queries.Add("IBMLiftForce", IBMQueries.IBMLiftForce()); return(c); }
private static IBMControl ShockTubeToro1WithIBMAndAVTemplate(int dgDegree, ExplicitSchemes explicitScheme, int explicitOrder, int noOfCellsX = 50, int noOfCellsY = 10) { 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; bool AV = true; 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 = Variables.Density; c.ShockSensor = new PerssonSensor(sensorVariable, sensorLimit); c.AddVariable(Variables.ShockSensor, 0); c.ArtificialViscosityLaw = new SmoothedHeavisideArtificialViscosityLaw(c.ShockSensor, 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(Variables.Density, dgDegree); c.AddVariable(Variables.Momentum.xComponent, dgDegree); c.AddVariable(Variables.Momentum.yComponent, dgDegree); c.AddVariable(Variables.Energy, dgDegree); c.AddVariable(Variables.Velocity.xComponent, dgDegree); c.AddVariable(Variables.Velocity.yComponent, dgDegree); c.AddVariable(Variables.Pressure, dgDegree); c.AddVariable(Variables.Rank, 0); if (AV) { c.AddVariable(Variables.ArtificialViscosity, 2); c.AddVariable(Variables.CFLArtificialViscosity, 0); } c.AddVariable(Variables.CFL, 0); c.AddVariable(Variables.CFLConvective, 0); if (c.ExplicitScheme.Equals(ExplicitSchemes.LTS)) { c.AddVariable(Variables.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.AddBoundaryCondition("AdiabaticSlipWall"); // Normal vector of initial shock Vector2D normalVector = new Vector2D(1, 0); // Direction vector of initial shock Vector2D r = new Vector2D(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(Variables.Pressure, X => pressureLeft - SmoothJump(DistanceFromPointToLine(X, p, r)) * (pressureLeft - pressureRight)); c.InitialValues_Evaluators.Add(Variables.Density, X => densityLeft - Jump(X[0]) * (densityLeft - densityRight)); c.InitialValues_Evaluators.Add(Variables.Pressure, X => pressureLeft - Jump(X[0]) * (pressureLeft - pressureRight)); c.InitialValues_Evaluators.Add(Variables.Velocity.xComponent, X => 0.0); c.InitialValues_Evaluators.Add(Variables.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, aggloThresh={3}, s0={4:0.0E-00}, CFLFrac={5}, ALTS {6}/{7}/{8}({9})", dgDegree, noOfCellsX, noOfCellsY, c.AgglomerationThreshold, sensorLimit, c.CFLFraction, c.ExplicitOrder, c.NumberOfSubGrids, c.ReclusteringInterval, c.maxNumOfSubSteps); return(c); }
public static IBMControl IBMBumpTest(int noOfCells, int dgDegree, int lsDegree, double CFL) { IBMControl c = new IBMControl(); // Solver Settings c.dtMin = 0.0; c.dtMax = 1.0; c.Endtime = 1000.0; c.CFLFraction = CFL; c.NoOfTimesteps = 250000; c.PrintInterval = 100; c.ResidualInterval = 100; c.ResidualLoggerType = ResidualLoggerTypes.ChangeRate | ResidualLoggerTypes.Query; c.ResidualBasedTerminationCriteria.Add("changeRate_L2_abs_rhoE", 1E-8); //Guid restart = new Guid(" 60688cbc-707d-4777-98e6-d237796ec14c"); //c.RestartInfo = new Tuple<Guid, BoSSS.Foundation.IO.TimestepNumber>(restart, -1); // Session Settings c.DbPath = @"C:\bosss_dbv2\GaussianBump_hhlr"; //c.DbPath = @"\\fdyprime\userspace\kraemer-eis\FDY-Cluster\dbe_bump\"; //c.DbPath = @"/home/kraemer/GaussianBump/dbev2/"; c.savetodb = true; c.saveperiod = 100; c.ProjectName = "TestsCutCells_(" + 2 * noOfCells + "x" + noOfCells + ")_CFL=" + c.CFLFraction + "_ls=" + lsDegree + "_p=" + dgDegree + "_agg=" + 0.53; c.ProjectDescription = "GaussianBump with Ma=0.5"; c.Tags.Add("Gaussian Bump"); c.Tags.Add("IBM Test"); // Solver Type c.DomainType = DomainTypes.StaticImmersedBoundary; c.ActiveOperators = Operators.Convection; c.ConvectiveFluxType = ConvectiveFluxTypes.OptimizedHLLC; // Time-Stepping Settings c.ExplicitScheme = ExplicitSchemes.RungeKutta; c.ExplicitOrder = 1; //Material Settings c.EquationOfState = IdealGas.Air; //IBM Settings c.LevelSetBoundaryTag = "adiabaticSlipWall"; c.LevelSetQuadratureOrder = 2 * lsDegree; c.CutCellQuadratureType = XQuadFactoryHelper.MomentFittingVariants.Classic; c.AgglomerationThreshold = 0.3; // Primary Variables 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, lsDegree); c.GridFunc = delegate { double xBoundary = 2.0625; double yBoundary = 2.0525; double yBottom = -0.01; double[] xnodes = GenericBlas.Linspace(-xBoundary, xBoundary, 2 * noOfCells + 1); double[] ynodes = GenericBlas.Linspace(yBottom, yBoundary, noOfCells + 1); GridCommons grid = Grid2D.Cartesian2DGrid( xnodes, ynodes ); grid.EdgeTagNames.Add(1, "supersonicinlet"); grid.EdgeTagNames.Add(2, "adiabaticSlipWall"); Func <double[], byte> func = delegate(double[] x) { if (Math.Abs(x[0] + xBoundary) < 1e-5) // Inflow { return(1); } else if (Math.Abs(x[0] - xBoundary) < 1e-5) // Outflow { return(1); } else if (Math.Abs(x[1] - yBoundary) < 1e-5) // Top { return(1); } else // Bottom { return(2); } }; grid.DefineEdgeTags(func); grid.Name = "IBM-[" + -xBoundary + "," + xBoundary + "]x[" + yBottom + "," + yBoundary + "]_Cells:(" + 2 * noOfCells + "x" + noOfCells + ")"; return(grid); }; // Functions Func <double[], double, double> rho = (X, t) => 1.0; Func <double[], double, double> u0 = (X, t) => 1.0; Func <double[], double, double> u1 = (X, t) => 0.0; Func <double[], double, double> pressure = (X, t) => 2.8571428571428; //Initial Values c.InitialValues_Evaluators.Add(Variables.Density, X => rho(X, 0.0)); c.InitialValues_Evaluators.Add(Variables.Velocity.xComponent, X => u0(X, 0.0)); c.InitialValues_Evaluators.Add(Variables.Velocity.yComponent, X => u1(X, 0.0)); c.InitialValues_Evaluators.Add(Variables.Pressure, X => pressure(X, 0.0)); c.LevelSetFunction = (X, t) => X[1] - 0.3939 * Math.Exp(-0.5 * X[0] * X[0]); //BoundaryConditions c.AddBoundaryCondition("adiabaticSlipWall"); c.AddBoundaryCondition("supersonicInlet", Variables.Density, rho); c.AddBoundaryCondition("supersonicInlet", Variables.Velocity.xComponent, u0); c.AddBoundaryCondition("supersonicInlet", Variables.Velocity.yComponent, u1); c.AddBoundaryCondition("supersonicInlet", Variables.Pressure, pressure); // Queries c.Queries.Add("L2ErrorEntropy", IBMQueries.L2Error(state => state.Entropy, (X, t) => 2.8571428571428)); return(c); }
public static IBMControl IBMBump(int noOfCells, int dgDegree, int lsDegree, double CFL, double epsilonX = 0.0, double epsilonY = 0.0) { IBMControl c = new IBMControl(); // Solver Settings c.dtMin = 0.0; c.dtMax = 1.0; c.Endtime = 1000.0; c.CFLFraction = CFL; c.NoOfTimesteps = 200000; c.PrintInterval = 100; c.ResidualInterval = 100; c.ResidualLoggerType = ResidualLoggerTypes.ChangeRate | ResidualLoggerTypes.Query; c.ResidualBasedTerminationCriteria.Add("changeRate_L2_abs_rhoE", 1E-8); //IBM Settings c.LevelSetBoundaryTag = "adiabaticSlipWall"; c.LevelSetQuadratureOrder = 2 * dgDegree; c.AgglomerationThreshold = 0.3; // NEXT STEP: SET THIS BOOL TO FALSE AND JUST USE IN POSITIVE SUB_VOLUME; // THEN TRY BOUNDING BOX APPROACH? // WHY THE HELL DOES THIS CONFIGURATION FAIL!??!?!?!? c.CutCellQuadratureType = XQuadFactoryHelper.MomentFittingVariants.Classic; c.SurfaceHMF_ProjectNodesToLevelSet = false; c.SurfaceHMF_RestrictNodes = true; c.SurfaceHMF_UseGaussNodes = false; c.VolumeHMF_NodeCountSafetyFactor = 3.0; c.VolumeHMF_RestrictNodes = true; c.VolumeHMF_UseGaussNodes = false; //Guid restart = new Guid(" 60688cbc-707d-4777-98e6-d237796ec14c"); //c.RestartInfo = new Tuple<Guid, BoSSS.Foundation.IO.TimestepNumber>(restart, -1); // Session Settings c.DbPath = @"\\fdyprime\userspace\kraemer-eis\FDY-Cluster\dbe_bump\"; //c.DbPath = @"/home/kraemer/GaussianBump/dbev2/"; c.savetodb = true; c.saveperiod = 20000; c.ProjectName = "BoxHMF=" + c.CutCellQuadratureType + "_Ma=0.5_(" + 2 * noOfCells + "x" + noOfCells + ")_CFL=" + c.CFLFraction + "_lsQuadOrder=" + c.LevelSetQuadratureOrder + "_p=" + dgDegree + "_agg=" + c.AgglomerationThreshold + "_epsX=" + epsilonX + "_epsY=" + epsilonY; c.ProjectDescription = "GaussianBump with Ma=0.5"; c.Tags.Add("Gaussian Bump"); c.Tags.Add("IBM Test"); // Solver Type c.DomainType = DomainTypes.StaticImmersedBoundary; c.ActiveOperators = Operators.Convection; c.ConvectiveFluxType = ConvectiveFluxTypes.OptimizedHLLC; // Time-Stepping Settings c.ExplicitScheme = ExplicitSchemes.RungeKutta; c.ExplicitOrder = 1; //Material Settings c.EquationOfState = IdealGas.Air; // Primary Variables 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, lsDegree); // Grid //switch (noOfCells) { // case 8: // c.GridGuid = new Guid("7337e273-542f-4b97-b592-895ac3422621"); // break; // case 16: // c.GridGuid = new Guid("32e5a779-2aef-4ea2-bdef-b158ae785f01"); // break; // case 32: // c.GridGuid = new Guid("e96c9f83-3486-4e45-aa3b-9a436445a059"); // break; // case 64: // c.GridGuid = new Guid("a86f1b67-4fa3-48ed-b6df-dcea370eb2c0"); // break; // default: // throw new ArgumentException("Wrong Grid Input"); //} c.GridFunc = delegate { double xBoundary = 12.0; double yBoundary = 12.0; double yBottom = 0.0; double[] xnodes = GenericBlas.Linspace(-xBoundary, xBoundary, 2 * noOfCells + 1); //double ySplit = 6.0; //int ySplitNoOfCells = (int) (0.5*noOfCells); //double[] ynodes1 = GenericBlas.Linspace(yBottom, ySplit, ySplitNoOfCells + 1); //double[] ynodes2 = GenericBlas.Linspace(ySplit, yBoundary, noOfCells-ySplitNoOfCells + 1); //ynodes1 = ynodes1.GetSubVector(0, ynodes1.Length - 1); //double[] ynodes = ArrayTools.Cat(ynodes1, ynodes2); double[] ynodes = GenericBlas.Linspace(yBottom, yBoundary, noOfCells + 1); GridCommons grid = Grid2D.Cartesian2DGrid( xnodes, ynodes ); grid.EdgeTagNames.Add(1, "supersonicinlet"); grid.EdgeTagNames.Add(2, "adiabaticSlipWall"); Func <double[], byte> func = delegate(double[] x) { if (Math.Abs(x[0] + xBoundary) < 1e-5) // Inflow { return(1); } else if (Math.Abs(x[0] - xBoundary) < 1e-5) // Outflow { return(1); } else if (Math.Abs(x[1] - yBoundary) < 1e-5) // Top { return(1); } else // Bottom { return(2); } }; grid.DefineEdgeTags(func); grid.Name = "IBM-[" + -xBoundary + "," + xBoundary + "]x[" + yBottom + "," + yBoundary + "]_Cells:(" + 2 * noOfCells + "x" + noOfCells + ")"; return(grid); }; // Functions Func <double[], double, double> rho = (X, t) => 1.0; Func <double[], double, double> u0 = (X, t) => 1.0; Func <double[], double, double> u1 = (X, t) => 0.0; Func <double[], double, double> pressure = (X, t) => 2.8571428571428; //Initial Values c.InitialValues_Evaluators.Add(Variables.Density, X => rho(X, 0.0)); c.InitialValues_Evaluators.Add(Variables.Velocity.xComponent, X => u0(X, 0.0)); c.InitialValues_Evaluators.Add(Variables.Velocity.yComponent, X => u1(X, 0.0)); c.InitialValues_Evaluators.Add(Variables.Pressure, X => pressure(X, 0.0)); c.LevelSetFunction = (X, t) => X[1] - epsilonY - 0.01 - 0.3939 * Math.Exp(-0.5 * (X[0] - epsilonX) * (X[0] - epsilonX)); //BoundaryConditions c.AddBoundaryCondition("adiabaticSlipWall"); c.AddBoundaryCondition("supersonicInlet", Variables.Density, rho); c.AddBoundaryCondition("supersonicInlet", Variables.Velocity.xComponent, u0); c.AddBoundaryCondition("supersonicInlet", Variables.Velocity.yComponent, u1); c.AddBoundaryCondition("supersonicInlet", Variables.Pressure, pressure); // Queries c.Queries.Add("L2ErrorEntropy", IBMQueries.L2Error(state => state.Entropy, (X, t) => 2.8571428571428)); return(c); }
public static IBMControl MovingFrameIBMIsentropicVortex(string dbPath = null, int dgDegree = 3, int noOfCellsPerDirection = 20, double initialLevelSetPosition = -0.9, double agglomerationThreshold = 0.2) { IBMControl c = new IBMControl(); double advectionVelocity = 1.0; c.DbPath = dbPath; c.savetodb = dbPath != null; c.saveperiod = 1; c.ProjectName = "Moving IBM Isentropic vortex"; c.Tags.Add("Isentropic vortex"); c.Tags.Add("Moving IBM"); c.DomainType = DomainTypes.MovingImmersedBoundary; c.ActiveOperators = Operators.Convection; c.ConvectiveFluxType = ConvectiveFluxTypes.MovingFrameRusanov; c.EquationOfState = IdealGas.Air; c.MachNumber = 1.0 / Math.Sqrt(c.EquationOfState.HeatCapacityRatio); c.TimesteppingStrategy = TimesteppingStrategies.MovingFrameFlux; c.ExplicitScheme = ExplicitSchemes.RungeKutta; c.ExplicitOrder = 1; 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[] nodes = GenericBlas.Linspace(-10.0, 10.0, noOfCellsPerDirection + 1); var grid = Grid2D.Cartesian2DGrid(nodes, nodes, periodicX: true, periodicY: false); grid.EdgeTagNames.Add(1, "adiabaticSlipWall"); grid.DefineEdgeTags(X => 1); return(grid); }; c.CutCellQuadratureType = XQuadFactoryHelper.MomentFittingVariants.Classic; c.SurfaceHMF_ProjectNodesToLevelSet = false; c.SurfaceHMF_RestrictNodes = true; c.SurfaceHMF_UseGaussNodes = false; c.VolumeHMF_NodeCountSafetyFactor = 3.0; c.VolumeHMF_RestrictNodes = true; c.VolumeHMF_UseGaussNodes = false; c.LevelSetQuadratureOrder = 10; c.LevelSetBoundaryTag = "supersonicInlet"; c.AgglomerationThreshold = agglomerationThreshold; c.SaveAgglomerationPairs = true; double gamma = c.EquationOfState.HeatCapacityRatio; Func <double[], double, double> x = (X, t) => X[0] - advectionVelocity * t; Func <double[], double, double> r = (X, t) => Math.Sqrt(x(X, t) * x(X, t) + X[1] * X[1]); Func <double[], double, double> phi = (X, t) => Math.Atan2(X[1], x(X, t)); Func <double[], double, double> rho = (X, t) => Math.Pow( 1.0 - 0.5 * (gamma - 1.0) / gamma * Math.Exp(1.0 - r(X, t) * r(X, t)), 1.0 / (gamma - 1.0)); Func <double[], double, double> p = (X, t) => Math.Pow(rho(X, t), gamma); Func <double[], double, double> uAbs = (X, t) => r(X, t) * Math.Exp(0.5 * (1.0 - r(X, t) * r(X, t))); Func <double[], double, double> u = (X, t) => advectionVelocity - Math.Sin(phi(X, t)) * uAbs(X, t); Func <double[], double, double> v = (X, t) => Math.Cos(phi(X, t)) * uAbs(X, t); c.InitialValues_Evaluators.Add(Variables.Density, X => rho(X, 0.0)); c.InitialValues_Evaluators.Add(Variables.Velocity.xComponent, X => u(X, 0.0)); c.InitialValues_Evaluators.Add(Variables.Velocity.yComponent, X => v(X, 0.0)); c.InitialValues_Evaluators.Add(Variables.Pressure, X => p(X, 0.0)); double amplitude = 0.3; c.LevelSetFunction = delegate(double[] X, double time) { double newLevelSetPosition = initialLevelSetPosition + amplitude * Math.Sin(10.0 * time); return(X[1] - newLevelSetPosition); }; c.LevelSetVelocity = (X, t) => new Vector3D( 0.0, 10.0 * amplitude * Math.Cos(10.0 * t), 0.0); c.AddBoundaryCondition("adiabaticSlipWall"); c.AddBoundaryCondition("supersonicInlet", Variables.Density, rho); c.AddBoundaryCondition("supersonicInlet", Variables.Velocity[0], u); c.AddBoundaryCondition("supersonicInlet", Variables.Velocity[1], v); c.AddBoundaryCondition("supersonicInlet", Variables.Pressure, p); c.dtMin = 0.0; c.dtMax = 1.0; c.CFLFraction = 0.1; c.Endtime = 10; c.NoOfTimesteps = 1000; return(c); }