/// <summary> /// Checks if any field contains NaN's or Inf's and throws an exception if this is the case. /// </summary> public bool CheckForNanOrInf(SIMPLEControl SolverConf) { bool FoundNanOrInf = false; switch (SolverConf.PhysicsMode) { case PhysicsMode.Incompressible: if (WorkingSetFlowField.CheckForNanOrInf()) { FoundNanOrInf = true; } break; case PhysicsMode.LowMach: if (WorkingSetFlowField.CheckForNanOrInf() || WorkingSetVariableDensity.CheckForNanOrInf() || WorkingSetLowMach.CheckForNanOrInf()) { FoundNanOrInf = true; } break; case PhysicsMode.Multiphase: if (WorkingSetFlowField.CheckForNanOrInf() || WorkingSetVariableDensity.CheckForNanOrInf() || WorkingSetMultiphase.CheckForNanOrInf()) { FoundNanOrInf = true; } break; default: throw new NotImplementedException(); } return(FoundNanOrInf); }
/// <summary> /// Ctor. /// </summary> /// <param name="GridDat"></param> /// <param name="Control"></param> /// <param name="IOFields"></param> /// <param name="RegisteredFields"></param> public VariableSetMultiphase(IGridData GridDat, SIMPLEControl Control, ICollection <DGField> IOFields, ICollection <DGField> RegisteredFields) : base(GridDat, Control, IOFields, RegisteredFields) { // Auxiliary field to calculate Lambda in Convective : LinearFlux Basis MeanBasis = new Basis(GridDat, 0); PhiMean = new SinglePhaseField(MeanBasis, "PhiMean"); }
/// <summary> /// Ctor. /// </summary> public MatrixAssemblyApproxInv(SIMPLEControl SolverConf, int LocalNoOfCells, SIMPLEMatrixAssembly Approx, int MaxUseMatrix = 1) : base(Approx.IsConstant, false, MaxUsePerIterMatrix: MaxUseMatrix) { m_Approx = Approx; m_SolverConf = SolverConf; m_LocalNoOfCells = LocalNoOfCells; base.Initialize(); }
/// <summary> /// Ctor. /// </summary> /// <param name="GridDat"></param> /// <param name="Control"></param> /// <param name="IOFields"></param> /// <param name="RegisteredFields"></param> public VariableSet(IGridData GridDat, SIMPLEControl Control, ICollection <DGField> IOFields, ICollection <DGField> RegisteredFields) { this.GridDat = GridDat; this.Control = Control; this.IOFields = IOFields; this.RegisteredFields = RegisteredFields; WorkingSetFlowField = new VariableSetFlowField(GridDat, Control, IOFields, RegisteredFields); }
/// <summary> /// Ctor /// </summary> /// <param name="GridDat"></param> /// <param name="Control"></param> /// <param name="IOFields"></param> /// <param name="RegisteredFields"></param> public VariableSetLowMach(IGridData GridDat, SIMPLEControl Control, ICollection <DGField> IOFields, ICollection <DGField> RegisteredFields) : base(GridDat, Control, IOFields, RegisteredFields) { // Auxiliary field to calculate Lambda in Convective : LinearFlux Basis MeanBasis = new Basis(GridDat, 0); TemperatureMean = new SinglePhaseField(MeanBasis, "TemperatureMean"); // Thermodynamic pressure - the correct value will be calculated in VariableSet.Initialize() if (ThermodynamicPressure.Current.Basis.Degree != 0) { throw new ApplicationException("The degree for ThermodynamicPressure in control-file has to be set to zero, since the ThermodynamicPressure is constant in space."); } }
/// <summary> /// Ctor. /// </summary> /// <param name="GridDat"></param> /// <param name="Control"></param> /// <param name="IOFields"></param> /// <param name="RegisteredFields"></param> /// <param name="SolverConf"></param> public VariableSetFlowField(IGridData GridDat, SIMPLEControl Control, ICollection <DGField> IOFields, ICollection <DGField> RegisteredFields) : base(GridDat, Control, IOFields, RegisteredFields) { // Auxiliary field to calculate Lambda in Convective : LinearFlux Basis MeanBasis = new Basis(GridDat, 0); SinglePhaseField[] _VelocityMean = new SinglePhaseField[GridDat.SpatialDimension]; _VelocityMean[0] = new SinglePhaseField(MeanBasis, "VelocityX_Mean"); _VelocityMean[1] = new SinglePhaseField(MeanBasis, "VelocityY_Mean"); if (GridDat.SpatialDimension == 3) { _VelocityMean[2] = new SinglePhaseField(MeanBasis, "VelocityZ_Mean"); } VelocityMean = new VectorField <SinglePhaseField>(_VelocityMean); }
/// <summary> /// Ctor. /// </summary> /// <param name="SolverConf"></param> public SIMPLEStepStatus(SIMPLEControl SolverConf) : this() { switch (SolverConf.PhysicsMode) { case PhysicsMode.Incompressible: case PhysicsMode.Multiphase: this.Timestep = new TimestepNumber(0, 0); break; case PhysicsMode.LowMach: this.Timestep = new TimestepNumber(0, 1, 0); break; default: throw new NotImplementedException(); } }
public SolverConfiguration( SIMPLEControl control, IGridData GridDat, VariableSet workingSet, int MPIRank) { this.SpatialDimension = GridDat.SpatialDimension; this.MPIRank = MPIRank; this.Control = control; this.BcMap = new IncompressibleBoundaryCondMap(GridDat, Control.BoundaryValues, Control.PhysicsMode); CheckSetupPressure(SpatialDimension); if (Control.PressureReferencePoint != null) { UnsetteledCoordinateMapping MappingPressure = new UnsetteledCoordinateMapping( new Basis(GridDat, workingSet.Pressure.Basis.Degree)); PressureReferencePointIndex = BoSSS.Solution.NSECommon.SolverUtils.GetIndexOfPressureReferencePoint(Control.PressureReferencePoint, MappingPressure, 0); if (PressureReferencePointIndex < 0) { throw new ApplicationException("Unknown error finding index for pressure reference point."); } } // SIP penalty for viscous part of momentum equation this.PenaltyViscMomentum = Control.ViscousPenaltyScaling; // SIP penalty for SIP pressure correction if ((Control.PredictorApproximation == PredictorApproximations.Identity_IP1)) { this.PenaltyPressureCorrection = Control.PressureCorrectionPenaltyScaling * GetSIPPenaltyBase(workingSet.Pressure.Basis.Degree, GridDat); } else if (Control.PressureCorrectionPenaltyScaling != 1.0) { throw new NotSupportedException("Extended property 'penalty_PressureCorrection' is only available for Identity_IP option."); } if (control.PhysicsMode == PhysicsMode.LowMach) { LowMachSIMPLEControl lowMachControl = control as LowMachSIMPLEControl; this.PenaltyHeatConduction = lowMachControl.PenaltyHeatConductionScaling * GetSIPPenaltyBase(workingSet.Pressure.Basis.Degree, GridDat); } this.Velocity = workingSet.Velocity; dt = control.Endtime / control.NoOfTimesteps; }
/// <summary> /// Create extended variables for variable density flows. /// </summary> /// <param name="control"></param> public void CreateExtendedVariables(SIMPLEControl control) { switch (control.PhysicsMode) { case PhysicsMode.Incompressible: break; case PhysicsMode.LowMach: WorkingSetVariableDensity = new VariableSetVariableDensity(GridDat, Control, IOFields, RegisteredFields); WorkingSetLowMach = new VariableSetLowMach(GridDat, Control, IOFields, RegisteredFields); break; case PhysicsMode.Multiphase: WorkingSetVariableDensity = new VariableSetVariableDensity(GridDat, Control, IOFields, RegisteredFields); WorkingSetMultiphase = new VariableSetMultiphase(GridDat, Control, IOFields, RegisteredFields); break; default: throw new NotImplementedException(); } }
/// <summary> /// Push WorkingSet to next time step. /// </summary> public void Push(SIMPLEControl SolverConf) { if (SolverConf.Algorithm == SolutionAlgorithms.Unsteady_SIMPLE) { this.Velocity.Push(); switch (SolverConf.PhysicsMode) { case PhysicsMode.Incompressible: break; case PhysicsMode.LowMach: this.Temperature.Push(); this.ThermodynamicPressure.Push(); break; case PhysicsMode.Multiphase: this.Phi.Push(); break; default: throw new NotImplementedException(); } } }
/// <summary> /// Ctor. /// </summary> /// <param name="GridDat"></param> /// <param name="Control"></param> /// <param name="IOFields"></param> /// <param name="RegisteredFields"></param> public BaseVariableSet(GridData GridDat, SIMPLEControl Control, ICollection <DGField> IOFields, ICollection <DGField> RegisteredFields) { InitFromAttributes.CreateFieldsAuto(this, GridDat, Control.FieldOptions, BoSSS.Foundation.XDG.XQuadFactoryHelper.MomentFittingVariants.Classic, IOFields, RegisteredFields); }
/// <summary> /// Update scalar field variables after solving scalar equation. /// </summary> /// <param name="SolverConf"></param> /// <param name="ModeRelaxScalar"></param> /// <param name="relax_scalar"></param> /// <param name="Scalar"></param> /// <param name="ScalarRes"></param> /// <param name="ScalarMean"></param> /// <param name="Rho"></param> /// <param name="Eta"></param> /// <param name="RhoMatrix"></param> /// <param name="EoS"></param> /// <param name="ThermodynamicPressure">Null for multiphase flows.</param> public static void UpdateScalarFieldVariables(SIMPLEControl SolverConf, RelaxationTypes ModeRelaxScalar, double relax_scalar, ScalarFieldHistory <SinglePhaseField> Scalar, SinglePhaseField ScalarRes, SinglePhaseField ScalarMean, SinglePhaseField Rho, SinglePhaseField Eta, QuadratureMatrix RhoMatrix, MaterialLaw EoS, SinglePhaseField ThermodynamicPressure, bool UpdateRhoVisc = true) { using (new FuncTrace()) { // Explicit Under-Relaxation of scalar variable // ============================================ if (ModeRelaxScalar == RelaxationTypes.Explicit) { // phi = alpha * phi_new + (1-alpha) * phi_old Scalar.Current.Scale(relax_scalar); Scalar.Current.Acc((1.0 - relax_scalar), ScalarRes); } // Scalar residual // =============== ScalarRes.Scale(-1.0); ScalarRes.Acc(1.0, Scalar.Current); // ScalarMean // ========== ScalarMean.Clear(); ScalarMean.AccLaidBack(1.0, Scalar.Current); // Thermodynamic pressure - only for Low-Mach number flows // ======================================================= switch (SolverConf.PhysicsMode) { case PhysicsMode.LowMach: LowMachSIMPLEControl lowMachConf = SolverConf as LowMachSIMPLEControl; if (lowMachConf.ThermodynamicPressureMode == ThermodynamicPressureMode.MassDetermined) { ThermodynamicPressure.Clear(); ThermodynamicPressure.AccConstant(((MaterialLawLowMach)EoS).GetMassDeterminedThermodynamicPressure(lowMachConf.InitialMass.Value, Scalar.Current)); } break; case PhysicsMode.Multiphase: break; default: throw new ApplicationException(); } if (UpdateRhoVisc) { // Density // ======= Rho.Clear(); Rho.ProjectFunction(1.0, EoS.GetDensity, null, Scalar.Current); RhoMatrix.Update(); // Viscosity // ========= Eta.Clear(); Eta.ProjectFunction(1.0, EoS.GetViscosity, null, Scalar.Current); } } }
/// <summary> /// Calculate Nusselt number for Low-Mach number flows. /// </summary> /// <param name="Timestep"></param> /// <param name="GridDat"></param> /// <param name="Temperature"></param> /// <param name="SolverConf"></param> void CalculateNusselt(TimestepNumber Timestep, IGridData GridDat, SinglePhaseField Temperature, SIMPLEControl SolverConf) { // Initialize calculation of Nusselt number. if (NusseltNum == null) { LowMachSIMPLEControl lowMachConf = SolverConf as LowMachSIMPLEControl; NusseltNum = new NusseltNumber(GridDat, Temperature, lowMachConf.EoS, lowMachConf.EdgeTagsNusselt); if ((base.MPIRank == 0) && (CurrentSessionInfo.ID != Guid.Empty)) { LogNusselt = base.DatabaseDriver.FsDriver.GetNewLog("Nusselt", CurrentSessionInfo.ID); LogNusselt.Write("Timestep"); for (int bc = 0; bc < NusseltNum.Nusselt.Length; bc++) { LogNusselt.Write("\t" + lowMachConf.EdgeTagsNusselt[bc]); } LogNusselt.WriteLine(); } } // Calculate Nusselt number NusseltNum.CalculateNusseltNumber(); // Write result to text file if ((base.MPIRank == 0) && (LogNusselt != null)) { LogNusselt.Write(Timestep.ToString()); for (int bc = 0; bc < NusseltNum.Nusselt.Length; bc++) { LogNusselt.Write("\t" + NusseltNum.Nusselt[bc].ToString("0.0000000000E+00", NumberFormatInfo.InvariantInfo)); } LogNusselt.WriteLine(); LogNusselt.Flush(); } }
/// <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(); } }
/// <summary> /// Ctor /// </summary> /// <param name="GridDat"></param> /// <param name="Control"></param> /// <param name="IOFields"></param> /// <param name="RegisteredFields"></param> public VariableSetVariableDensity(IGridData GridDat, SIMPLEControl Control, ICollection <DGField> IOFields, ICollection <DGField> RegisteredFields) : base(GridDat, Control, IOFields, RegisteredFields) { }