/// <summary> /// ... /// </summary> public override void PostRestart(double time, TimestepNumber timestep) { //InitLogEnergyOrrSommerfeld(); WorkingSet.Initialize(Control); // Create WorkingSetMatrices switch (Control.PhysicsMode) { case PhysicsMode.Incompressible: break; case PhysicsMode.LowMach: LowMachSIMPLEControl lowMachConf = Control as LowMachSIMPLEControl; m_WorkingSetMatrices = new VariableMatrices(base.GridData, WorkingSet.VelBasis, WorkingSet.PressureBasis, lowMachConf.EoS, WorkingSet.Temperature.Current); break; case PhysicsMode.Multiphase: MultiphaseSIMPLEControl multiphaseConf = Control as MultiphaseSIMPLEControl; m_WorkingSetMatrices = new VariableMatrices(base.GridData, WorkingSet.VelBasis, WorkingSet.PressureBasis, multiphaseConf.EoS, WorkingSet.Phi.Current); break; default: throw new NotImplementedException(); } WorkingSet.CheckForNanOrInf(Control); // push start values to history WorkingSet.Push(Control); }
/// <summary> /// Ctor. /// </summary> /// <param name="LevelSetOperators"></param> /// <param name="multiphaseControl"></param> /// <param name="BDF"></param> public MatrixFactoryLevelSet(OperatorFactoryLevelSet LevelSetOperators, int LocalNoOfCells, SolverConfiguration solverConf, BDFScheme BDF) { LevelSet = new MatrixAssemblyLevelSet(LevelSetOperators.LevelSetAdvection); MultiphaseSIMPLEControl multiphaseControl = solverConf.Control as MultiphaseSIMPLEControl; if (multiphaseControl.LevelSetRelaxationType == RelaxationTypes.Implicit) { LevelSetApprox = new MatrixAssemblyApprox( solverConf, LocalNoOfCells, LevelSet, BDF, 2 * multiphaseControl.PredictorApproximationUpdateCycle); } }
/// <summary> /// Ctor. /// </summary> /// <param name="solverConf"></param> /// <param name="sparseSolver"></param> /// <param name="MatAsmblyScalar"></param> /// <param name="MatAsmblyScalarApprox"></param> /// <param name="Scalar"></param> /// <param name="BDF"></param> public MultiphaseSolverLevelSet(SolverConfiguration solverConf, ISparseSolver sparseSolver, SIMPLEMatrixAssembly MatAsmblyScalar, SIMPLEMatrixAssembly MatAsmblyScalarApprox, ScalarFieldHistory <SinglePhaseField> Scalar, BDFScheme BDF) : base(solverConf, sparseSolver) { m_MatAsmblyLevelSet = MatAsmblyScalar; m_MatAsmblyLevelSetApprox = MatAsmblyScalarApprox; m_LevelSet = Scalar; m_solverConf = solverConf; m_multiphaseControl = solverConf.Control as MultiphaseSIMPLEControl; m_RelaxFactor = (1.0 - m_multiphaseControl.RelaxationFactorLevelSet) / m_multiphaseControl.RelaxationFactorLevelSet; m_ModeRelaxLevelSet = m_multiphaseControl.LevelSetRelaxationType; m_BDF = BDF; }
/// <summary> /// /// </summary> protected override void CreateFields() { using (new FuncTrace()) { // create fields for flow field WorkingSet = new VariableSet(base.GridData, Control, base.m_IOFields, base.m_RegisteredFields); // create extended fields for variable density solvers WorkingSet.CreateExtendedVariables(Control); // read settings for SIMPLE-algorithm SolverConf = new SolverConfiguration( Control, GridData, WorkingSet, base.MPIRank); // Plot analytic solution PlotAnalyticSolution(Control.AnalyticVelocityX, WorkingSet.VelBasis, "VelocityX_Ana"); PlotAnalyticSolution(Control.AnalyticVelocityY, WorkingSet.VelBasis, "VelocityY_Ana"); if (SolverConf.SpatialDimension == 3) { PlotAnalyticSolution(Control.AnalyticVelocityZ, WorkingSet.VelBasis, "VelocityZ_Ana"); } PlotAnalyticSolution(Control.AnalyticPressure, WorkingSet.PressureBasis, "Pressure_Ana"); switch (Control.PhysicsMode) { case PhysicsMode.Incompressible: break; case PhysicsMode.LowMach: LowMachSIMPLEControl lowMachConf = Control as LowMachSIMPLEControl; PlotAnalyticSolution(lowMachConf.AnalyticTemperature, WorkingSet.TemperatureBasis, "Temperature_Ana"); PlotAnalyticSolution(lowMachConf.AnalyticDensity, WorkingSet.TemperatureBasis, "Density_Ana"); break; case PhysicsMode.Multiphase: MultiphaseSIMPLEControl multiphaseConf = Control as MultiphaseSIMPLEControl; PlotAnalyticSolution(multiphaseConf.AnalyticLevelSet, WorkingSet.LevelSetBasis, "LevelSet_Ana"); PlotAnalyticSolution(multiphaseConf.AnalyticDensity, WorkingSet.LevelSetBasis, "Density_Ana"); break; default: throw new NotImplementedException(); } } }
/// <summary> /// Ctor. /// </summary> /// <param name="SolverConf"></param> /// <param name="WorkingSet"></param> /// <param name="WorkingSetMatrices"></param> public SIMPLEStepMultiphase(SolverConfiguration SolverConf, VariableSet WorkingSet, VariableMatrices WorkingSetMatrices) : base(SolverConf, WorkingSet, WorkingSetMatrices) { this.SolverConf = SolverConf; this.MultiphaseControl = SolverConf.Control as MultiphaseSIMPLEControl; if (this.MultiphaseControl == null) { throw new ArgumentException("Invalid configuration", nameof(SolverConf)); } // Construct SIMPLEOperators UnsetteledCoordinateMapping LevelSetMapping = new UnsetteledCoordinateMapping(WorkingSet.LevelSetBasis); OperatorsLevelSet = new OperatorFactoryLevelSet(LevelSetMapping, WorkingSet.Velocity.Current, WorkingSet.VelocityMean, SolverConf); // Construct matrix assemblies MatrixAssembliesLevelSet = new MatrixFactoryLevelSet(OperatorsLevelSet, LevelSetMapping.GridDat.iLogicalCells.NoOfLocalUpdatedCells, SolverConf, base.BDF); }
/// <summary> /// Initializes velocity and pressure /// </summary> protected override void SetInitial() { //WriteQuadNodesOrrSommerfeld(); //InitOrrSommerfeld(); base.SetInitial(); //TaylorVortexHack(); WorkingSet.Initialize(Control); // Create WorkingSetMatrices switch (Control.PhysicsMode) { case PhysicsMode.Incompressible: break; case PhysicsMode.LowMach: LowMachSIMPLEControl lowMachConf = Control as LowMachSIMPLEControl; m_WorkingSetMatrices = new VariableMatrices(base.GridData, WorkingSet.VelBasis, WorkingSet.PressureBasis, lowMachConf.EoS, WorkingSet.Temperature.Current); break; case PhysicsMode.Multiphase: MultiphaseSIMPLEControl multiphaseConf = Control as MultiphaseSIMPLEControl; m_WorkingSetMatrices = new VariableMatrices(base.GridData, WorkingSet.VelBasis, WorkingSet.PressureBasis, multiphaseConf.EoS, WorkingSet.Phi.Current); break; default: throw new NotImplementedException(); } WorkingSet.CheckForNanOrInf(Control); // push start values to history WorkingSet.Push(Control); }
/// <summary> /// /// </summary> protected override double RunSolverOneStep(int TimestepNo, double phystime, double dt) { using (var tr = new FuncTrace()) { tr.Info("Performing time iteration No. " + TimestepNo); // Set dt and SIMPLEStatus switch (Control.Algorithm) { case SolutionAlgorithms.Steady_SIMPLE: { dt = 0.0; break; } case SolutionAlgorithms.Unsteady_SIMPLE: { dt = SolverConf.dt; SIMPLEStatus.NextTimestep(); break; } } // some console-output if (base.MPIRank == 0) { switch (Control.Algorithm) { case SolutionAlgorithms.Steady_SIMPLE: Console.WriteLine("Starting steady calculation...\n"); Console.WriteLine("Starting SIMPLE-Iterations...\n"); break; case SolutionAlgorithms.Unsteady_SIMPLE: Console.WriteLine("Starting time step #" + TimestepNo + "...\n"); Console.WriteLine("Starting SIMPLE-Iterations...\n"); break; default: throw new NotImplementedException(); } } do { // do one SIMPLE iteration SIMPLEStatus.NextSIMPLEIteration(); SIMPLEStep.OverallIteration(ref SIMPLEStatus, dt, ResLogger); TerminationKey = WorkingSet.CheckForNanOrInf(Control); if (TerminationKey) { m_Logger.Warn("Found Nan in some field."); if (base.MPIRank == 0) { Console.WriteLine("ERROR: Found Nan in some field."); } Console.ReadKey(); } if ((Control.PhysicsMode == PhysicsMode.LowMach) && (SolverConf.Control.As <LowMachSIMPLEControl>().EdgeTagsNusselt != null)) { CalculateNusselt(SIMPLEStatus.Timestep, base.GridData, WorkingSet.Temperature.Current, Control); } // save to database if (SIMPLEStatus.SaveStep) { SaveToDatabase(SIMPLEStatus.Timestep, phystime); } // calculate errors int QuadDegreePressure = 20; int QuadDegreeVel = 20; ResLogger.ComputeL2Error(WorkingSet.Pressure, Control.AnalyticPressure, QuadDegreePressure, "p_ana"); ResLogger.ComputeL2Error(WorkingSet.Velocity.Current[0], Control.AnalyticVelocityX, QuadDegreeVel, "u_ana"); ResLogger.ComputeL2Error(WorkingSet.Velocity.Current[1], Control.AnalyticVelocityY, QuadDegreeVel, "v_ana"); if (SolverConf.SpatialDimension == 3) { ResLogger.ComputeL2Error(WorkingSet.Velocity.Current[2], Control.AnalyticVelocityZ, QuadDegreeVel, "w_ana"); } switch (Control.PhysicsMode) { case PhysicsMode.Incompressible: break; case PhysicsMode.LowMach: LowMachSIMPLEControl lowMachConf = Control as LowMachSIMPLEControl; ResLogger.ComputeL2Error(WorkingSet.Temperature.Current, lowMachConf.AnalyticTemperature, QuadDegreeVel, "T_ana"); ResLogger.ComputeL2Error(WorkingSet.Rho, lowMachConf.AnalyticDensity, QuadDegreeVel, "Rho_ana"); break; case PhysicsMode.Multiphase: MultiphaseSIMPLEControl multiphaseConf = Control as MultiphaseSIMPLEControl; ResLogger.ComputeL2Error(WorkingSet.Phi.Current, multiphaseConf.AnalyticLevelSet, QuadDegreeVel, "Phi_ana"); ResLogger.ComputeL2Error(WorkingSet.Rho, multiphaseConf.AnalyticDensity, QuadDegreeVel, "Rho_ana"); break; default: throw new NotImplementedException(); } // terminate SIMPLE in case of divergence if (ResLogger.Residuals["L2Norm p'"] > 1.0E+10) { TerminationKey = true; } // push residual logger to next iteration switch (Control.Algorithm) { case SolutionAlgorithms.Steady_SIMPLE: ResLogger.NextIteration(false); break; case SolutionAlgorithms.Unsteady_SIMPLE: ResLogger.NextIteration(true); break; default: throw new NotImplementedException(); } }while (!SIMPLEStatus.IsConverged && !SIMPLEStatus.TerminateSIMPLE && !TerminationKey); // determine cause for end of SIMPLE iterations if (SIMPLEStatus.IsConverged) { tr.Info("Solution converged."); } else if (SIMPLEStatus.TerminateSIMPLE) { if (SIMPLEStatus.SIMPLEStepNo == Control.MaxNoSIMPLEsteps) { SIMPLEStatus.CntMaxNoSIMPLEsteps++; m_Logger.Warn("MaxNoSIMPLEsteps are reached."); } else { m_Logger.Warn("Unknown reason for terminating SIMPLE iterations - should not happen."); } } else { m_Logger.Error("Solution diverged."); } // save the new timestep switch (Control.Algorithm) { case SolutionAlgorithms.Steady_SIMPLE: break; case SolutionAlgorithms.Unsteady_SIMPLE: WorkingSet.Push(Control); ResLogger.NextTimestep(false); break; default: throw new NotImplementedException(); } // some console-output if (SIMPLEStatus.IsConverged) { Console.WriteLine("\nINFO: Done SIMPLE-Iterations - Solution converged.\n"); } else if (SIMPLEStatus.SIMPLEStepNo == Control.MaxNoSIMPLEsteps) { Console.WriteLine("\nWARNING: Done SIMPLE-Iterations - Maximum number of SIMPLE steps was reached.\n"); } else { Console.WriteLine("\nERROR: Calculation was terminated - Solution diverged.\n"); } switch (Control.Algorithm) { case SolutionAlgorithms.Steady_SIMPLE: Console.WriteLine("Done steady calculation."); break; case SolutionAlgorithms.Unsteady_SIMPLE: Console.WriteLine("Done time step #" + TimestepNo + ".\n"); break; default: throw new NotImplementedException(); } //LogEnergyOrrSommerfeld(TimestepNo, phystime, dt); if (Control.EdgeTagsDragAndLift != null) { CalculateDragAndLift(phystime); } //Log temperature history tall cavity //LogTemperature(phystime, this.WorkingSet.Temperature.Current); return(dt); } }
/// <summary> /// Initialize all variables, which are not /// initialized by the control-file. /// Has to be called after <see cref="Application.SetInitial()"/> /// </summary> public void Initialize(SIMPLEControl SolverConf) { // Set history length according to time order if (SolverConf.Algorithm == SolutionAlgorithms.Unsteady_SIMPLE) { this.Velocity.IncreaseHistoryLength(SolverConf.TimeOrder); } this.VelocityMean.Clear(); this.VelocityMean.AccLaidBack(1.0, this.Velocity.Current); switch (SolverConf.PhysicsMode) { case PhysicsMode.Incompressible: break; case PhysicsMode.LowMach: { LowMachSIMPLEControl lowMachConf = SolverConf as LowMachSIMPLEControl; // Set history length according to time order if (SolverConf.Algorithm == SolutionAlgorithms.Unsteady_SIMPLE) { this.Temperature.IncreaseHistoryLength(SolverConf.TimeOrder); } // Initialize TemperatureMean this.TemperatureMean.Clear(); this.TemperatureMean.AccLaidBack(1.0, this.Temperature.Current); // Initialize ThermodynamicPressure this.ThermodynamicPressure.Current.Clear(); switch (lowMachConf.ThermodynamicPressureMode) { case ThermodynamicPressureMode.Constant: this.ThermodynamicPressure.Current.AccConstant(1.0); break; case ThermodynamicPressureMode.MassDetermined: if (SolverConf.Algorithm == SolutionAlgorithms.Unsteady_SIMPLE) { this.ThermodynamicPressure.IncreaseHistoryLength(SolverConf.TimeOrder); } this.ThermodynamicPressure.Current.AccConstant( lowMachConf.EoS.GetMassDeterminedThermodynamicPressure( lowMachConf.InitialMass.Value, this.Temperature.Current)); break; default: throw new NotImplementedException(); } // Initialize EoS lowMachConf.EoS.Initialize(this.ThermodynamicPressure); // Initialize Density this.Rho.Clear(); this.Rho.ProjectFunction(1.0, lowMachConf.EoS.GetDensity, null, this.Temperature.Current); // Initialize Viscosity this.Eta.Clear(); this.Eta.ProjectFunction(1.0, lowMachConf.EoS.GetViscosity, null, this.Temperature.Current); } break; case PhysicsMode.Multiphase: { MultiphaseSIMPLEControl multiphaseConf = SolverConf as MultiphaseSIMPLEControl; // Set history length according to time order if (SolverConf.Algorithm == SolutionAlgorithms.Unsteady_SIMPLE) { this.Phi.IncreaseHistoryLength(SolverConf.TimeOrder); } // Initialize PhiMean this.PhiMean.Clear(); this.PhiMean.AccLaidBack(1.0, this.Phi.Current); // Initialize Density this.Rho.Clear(); this.Rho.ProjectFunction(1.0, multiphaseConf.EoS.GetDensity, null, this.Phi.Current); // Initialize Viscosity this.Eta.Clear(); this.Eta.ProjectFunction(1.0, multiphaseConf.EoS.GetViscosity, null, this.Phi.Current); } break; default: throw new NotImplementedException(); } }