예제 #1
0
        public override void OverallIteration(ref SIMPLEStepStatus SIMPLEStatus, double dt, ResidualLogger ResLogger)
        {
            using (new FuncTrace()) {
                // Solve flow field and scalar field
                base.SolveFlowFieldEquations(ref SIMPLEStatus, dt, ResLogger);
                this.SolveScalarEquations(ref SIMPLEStatus, dt, ResLogger);

                // Check convergence
                if (ResLogger.Residuals["L2Norm p'"] < MultiphaseControl.L2NormPressureCorrection &&
                    ResLogger.Residuals["L2Norm u_res"] < MultiphaseControl.L2NormVelocityResidual &&
                    ResLogger.Residuals["L2Norm v_res"] < MultiphaseControl.L2NormVelocityResidual &&
                    ResLogger.Residuals["L2Norm Phi_res"] < MultiphaseControl.L2NormLevelSetResidual)
                {
                    if (SolverConf.SpatialDimension == 2)
                    {
                        SIMPLEStatus.IsConverged = true;
                    }
                    else if (ResLogger.Residuals["L2Norm w_res"] < MultiphaseControl.L2NormVelocityResidual)
                    {
                        SIMPLEStatus.IsConverged = true;
                    }
                }

                // Set SIMPLEStatus
                if (MultiphaseControl.MaxNoSIMPLEsteps == SIMPLEStatus.SIMPLEStepNo)
                {
                    SIMPLEStatus.TerminateSIMPLE = true;
                }

                if ((MultiphaseControl.Algorithm == SolutionAlgorithms.Steady_SIMPLE) && (SIMPLEStatus.SIMPLEStepNo % MultiphaseControl.SavePeriodSIMPLE == 0))
                {
                    SIMPLEStatus.SaveStep = true;
                }
            }
        }
예제 #2
0
        /// <summary>
        ///
        /// </summary>
        protected override void CreateEquationsAndSolvers(GridUpdateDataVaultBase L)
        {
            using (new FuncTrace()) {
                // Create SIMPLEStatus
                SIMPLEStatus = new SIMPLEStepStatus(Control);

                // Create SIMPLEStep
                switch (Control.PhysicsMode)
                {
                case PhysicsMode.Incompressible:
                    SIMPLEStep = new SIMPLEStepIncompressible(SolverConf, WorkingSet);
                    break;

                case PhysicsMode.LowMach:
                    SIMPLEStep = new SIMPLEStepLowMach(SolverConf, WorkingSet, WorkingSetMatrices);
                    break;

                case PhysicsMode.Multiphase:
                    SIMPLEStep = new SIMPLEStepMultiphase(SolverConf, WorkingSet, WorkingSetMatrices);
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
        }
예제 #3
0
        protected override void SolveScalarEquations(ref SIMPLEStepStatus SIMPLEStatus, double dt, ResidualLogger ResLogger)
        {
            // Update temperature field SIMPLE operators (first!) and matrix assemblies (second!)
            // ==================================================================================

            OperatorsTemperature.TemperatureConvection.Update();
            OperatorsTemperature.HeatConduction.Update();
            MatrixAssembliesTemperature.Temperature.Update();
            if ((LowMachControl.RelaxationModeTemperature == RelaxationTypes.Implicit) &&
                !MatrixAssembliesTemperature.TemperatureApprox.IsConstant &&
                ((SIMPLEStatus.SIMPLEStepNo - 1) % LowMachControl.PredictorApproximationUpdateCycle == 0))
            {
                MatrixAssembliesTemperature.TemperatureApprox.Update();
            }

            // Temperature solver
            // ==================

            SIMPLESolver TemperatureSolver = new LowMachSolverTemperature(
                this.SolverConf,
                LowMachControl.TemperatureSolverFactory(),
                base.WorkingSetMatrices.Rho.Matrix,
                this.MatrixAssembliesTemperature.Temperature,
                this.MatrixAssembliesTemperature.TemperatureApprox,
                base.WorkingSet.Temperature,
                base.BDF,
                LowMachControl.EoS,
                base.WorkingSet.ThermodynamicPressure);

            base.WorkingSet.TemperatureRes.Clear();
            base.WorkingSet.TemperatureRes.Acc(1.0, base.WorkingSet.Temperature.Current);

            TemperatureSolver.Solve(base.WorkingSet.Temperature.Current.CoordinateVector, dt);
            TemperatureSolver.Dispose();

            // Update temperature field variables
            // ==================================

            SIMPLEStepUtils.UpdateScalarFieldVariables(
                LowMachControl,
                LowMachControl.RelaxationModeTemperature,
                LowMachControl.RelexationFactorTemperature,
                base.WorkingSet.Temperature,
                base.WorkingSet.TemperatureRes,
                base.WorkingSet.TemperatureMean,
                base.WorkingSet.Rho,
                base.WorkingSet.Eta,
                base.WorkingSetMatrices.Rho,
                LowMachControl.EoS,
                base.WorkingSet.ThermodynamicPressure.Current);

            // Calculate residuals temperature
            // ===============================

            ResLogger.ComputeL2Norm(base.WorkingSet.TemperatureRes);
        }
예제 #4
0
        /// <summary>
        /// One segregated iteration,
        /// i.e. solving either flow field or temperature field in one iteration.
        /// </summary>
        /// <param name="SIMPLEStatus"></param>
        /// <param name="dt"></param>
        /// <param name="ResLogger"></param>
        private void SegregatedIteration(ref SIMPLEStepStatus SIMPLEStatus, double dt, ResidualLogger ResLogger)
        {
            if (CntInnerIterSegregatedStep <= LowMachControl.MaxFlowSolverIterations)
            {
                // Solve equations flow field
                base.SolveFlowFieldEquations(ref SIMPLEStatus, dt, ResLogger);

                // Check convergence flow field
                if (ResLogger.Residuals["L2Norm p'"] < LowMachControl.L2NormPressureCorrection &&
                    ResLogger.Residuals["L2Norm u_res"] < LowMachControl.L2NormVelocityResidual &&
                    ResLogger.Residuals["L2Norm v_res"] < LowMachControl.L2NormVelocityResidual)
                {
                    if (base.SolverConf.SpatialDimension == 2)
                    {
                        CntInnerIterSegregatedStep = LowMachControl.MaxFlowSolverIterations;
                    }
                    else if (ResLogger.Residuals["L2Norm w_res"] < LowMachControl.L2NormVelocityResidual)
                    {
                        CntInnerIterSegregatedStep = LowMachControl.MaxFlowSolverIterations;
                    }
                }

                // Set SIMPLEStatus
                if (CntInnerIterSegregatedStep == LowMachControl.MaxFlowSolverIterations)
                {
                    SIMPLEStatus.SaveStep = true;
                }

                // Workaround for plotting residuals
                ResLogger.ComputeL2Norm(base.WorkingSet.TemperatureRes);
            }
            else
            {
                // Solve temperature equation
                this.SolveScalarEquations(ref SIMPLEStatus, dt, ResLogger);

                // Check convergence temperature field
                if ((ResLogger.Residuals["L2Norm T_res"] < LowMachControl.L2NormTemperatureResidual) ||
                    (CntInnerIterSegregatedStep == LowMachControl.MaxFlowSolverIterations + LowMachControl.MaxTemperatureSolverIterations))
                {
                    CntInnerIterSegregatedStep = 0;
                    SIMPLEStatus.NextSegregatedStep();
                    // Set SIMPLEStatus
                    SIMPLEStatus.SaveStep = true;
                    if (SIMPLEStatus.Timestep[1] > LowMachControl.MaxNoSIMPLEsteps)
                    {
                        SIMPLEStatus.IsConverged = true;
                    }
                }

                // Workaround for plotting residuals
                ResLogger.ComputeL2Norm(WorkingSet.Pressure_Correction, "p'");
                ResLogger.ComputeL2Norm(WorkingSet.VelRes);
            }
            CntInnerIterSegregatedStep++;
        }
예제 #5
0
 public override void OverallIteration(ref SIMPLEStepStatus SIMPLEStatus, double dt, ResidualLogger ResLogger)
 {
     if ((LowMachControl.MaxFlowSolverIterations == 1) && (LowMachControl.MaxTemperatureSolverIterations == 1))
     {
         FullyCoupledIteration(ref SIMPLEStatus, dt, ResLogger);
     }
     else
     {
         SegregatedIteration(ref SIMPLEStatus, dt, ResLogger);
     }
 }
예제 #6
0
        /// <summary>
        /// One fully coupled iteration,
        /// i.e. solving flow field and temperature field in one iteration.
        /// </summary>
        /// <param name="SIMPLEStatus"></param>
        /// <param name="dt"></param>
        /// <param name="ResLogger"></param>
        private void FullyCoupledIteration(ref SIMPLEStepStatus SIMPLEStatus, double dt, ResidualLogger ResLogger)
        {
            // Solve flow field and temperature field
            base.SolveFlowFieldEquations(ref SIMPLEStatus, dt, ResLogger);
            this.SolveScalarEquations(ref SIMPLEStatus, dt, ResLogger);

            // Check convergence
            if (ResLogger.Residuals["L2Norm p'"] < LowMachControl.L2NormPressureCorrection &&
                ResLogger.Residuals["L2Norm u_res"] < LowMachControl.L2NormVelocityResidual &&
                ResLogger.Residuals["L2Norm v_res"] < LowMachControl.L2NormVelocityResidual &&
                ResLogger.Residuals["L2Norm T_res"] < LowMachControl.L2NormTemperatureResidual)
            {
                if (base.SolverConf.SpatialDimension == 2)
                {
                    SIMPLEStatus.IsConverged = true;
                }
                else if (ResLogger.Residuals["L2Norm w_res"] < LowMachControl.L2NormVelocityResidual)
                {
                    SIMPLEStatus.IsConverged = true;
                }
            }

            // Set SIMPLEStatus
            if (LowMachControl.MaxNoSIMPLEsteps == SIMPLEStatus.SIMPLEStepNo)
            {
                SIMPLEStatus.TerminateSIMPLE = true;
            }

            if ((LowMachControl.Algorithm == SolutionAlgorithms.Steady_SIMPLE) && (SIMPLEStatus.SIMPLEStepNo % LowMachControl.SavePeriodSIMPLE == 0))
            {
                SIMPLEStatus.SaveStep = true;
            }

            /*
             * // Solve only temperature equation (only used for debugging).
             * this.SolveScalarEquations(ref SIMPLEStatus, dt, ResLogger);
             * SIMPLEStatus.SaveStep = true;
             *
             * // Check convergence temperature field
             * if ((ResLogger.Residuals["L2Norm T_res"] < base.SolverConf.L2NormTemperatureRes)
             || (SolverConf.MaxNoSIMPLEsteps == SIMPLEStatus.SIMPLEStepNo)) {
             ||
             || // Set SIMPLEStatus
             || SIMPLEStatus.TerminateSIMPLE = true;
             ||}
             ||
             ||// Workaround for plotting residuals
             ||ResLogger.ComputeL2Norm(WorkingSet.Pressure_Correction, "p'");
             ||ResLogger.ComputeL2Norm(WorkingSet.VelRes);*/
        }
예제 #7
0
        protected override void SolveScalarEquations(ref SIMPLEStepStatus SIMPLEStatus, double dt, ResidualLogger ResLogger)
        {
            // Update level-set SIMPLE operators (first!) and matrix assemblies (second!)
            // ==========================================================================
            OperatorsLevelSet.LevelSetAdvection.Update();
            MatrixAssembliesLevelSet.LevelSet.Update();
            if (base.UpdateApproximations && (MultiphaseControl.LevelSetRelaxationType == RelaxationTypes.Implicit))
            {
                MatrixAssembliesLevelSet.LevelSetApprox.Update();
            }

            // Level-Set solver
            // ================

            SIMPLESolver LevelSetSolver = new MultiphaseSolverLevelSet(
                SolverConf,
                MultiphaseControl.LevelSetSolverFactory(),
                MatrixAssembliesLevelSet.LevelSet,
                MatrixAssembliesLevelSet.LevelSetApprox,
                base.WorkingSet.Phi,
                base.BDF);

            base.WorkingSet.PhiRes.Clear();
            base.WorkingSet.PhiRes.Acc(1.0, base.WorkingSet.Phi.Current);

            LevelSetSolver.Solve(base.WorkingSet.Phi.Current.CoordinateVector, dt);
            LevelSetSolver.Dispose();

            // Update level-set variables
            // ==========================

            SIMPLEStepUtils.UpdateScalarFieldVariables(
                MultiphaseControl,
                MultiphaseControl.LevelSetRelaxationType,
                MultiphaseControl.RelaxationFactorLevelSet,
                base.WorkingSet.Phi,
                base.WorkingSet.PhiRes,
                base.WorkingSet.PhiMean,
                base.WorkingSet.Rho,
                base.WorkingSet.Eta,
                base.WorkingSetMatrices.Rho,
                MultiphaseControl.EoS,
                null);

            // Calculate residuals level-set
            // =============================

            ResLogger.ComputeL2Norm(base.WorkingSet.PhiRes);
        }
예제 #8
0
 /// <summary>
 /// Solve scalar equations, i.e.
 /// level-set equation for multiphase and
 /// temperature equation for Low-Mach.
 /// </summary>
 /// <param name="dt"></param>
 protected abstract void SolveScalarEquations(ref SIMPLEStepStatus SIMPLEStatus, double dt, ResidualLogger ResLogger);
예제 #9
0
        /// <summary>
        /// Solve flow field equations, i.e.
        /// Predictor for velocity and
        /// Corrector for pressure correction.
        /// </summary>
        /// <param name="SIMPLEStatus"></param>
        /// <param name="dt"></param>
        /// <param name="ResLogger"></param>
        protected void SolveFlowFieldEquations(ref SIMPLEStepStatus SIMPLEStatus, double dt, ResidualLogger ResLogger)
        {
            // Update flow field SIMPLE operators (first!) and matrix assemblies (second!)
            // ===========================================================================

            UpdateApproximations = (!MatrixAssembliesFlowField.PredictorApprox[0].IsConstant &&
                                    ((SIMPLEStatus.SIMPLEStepNo - 1) % SolverConf.Control.PredictorApproximationUpdateCycle == 0)) ? true : false;

            for (int i = 0; i < SolverConf.SpatialDimension; i++)
            {
                OperatorsFlowField.Convection[i].Update();
                OperatorsFlowField.Visc[i].Update();
                OperatorsFlowField.Swip2[i].Update();
                if (SolverConf.Control.PhysicsMode == PhysicsMode.LowMach)
                {
                    OperatorsFlowField.Swip3[i].Update();
                    OperatorsFlowField.DivergenceConti[i].Update();
                }
                for (int j = 0; j < SolverConf.SpatialDimension; j++)
                {
                    MatrixAssembliesFlowField.ViscSplit[i, j].Update();
                }
                MatrixAssembliesFlowField.Predictor[i].Update();
            }

            if (UpdateApproximations)
            {
                for (int i = 0; i < SolverConf.SpatialDimension; i++)
                {
                    MatrixAssembliesFlowField.PredictorApprox[i].Update();
                    MatrixAssembliesFlowField.PredictorApproxInv[i].Update();
                }
                if (SolverConf.Control.PhysicsMode == PhysicsMode.Multiphase)
                {
                    MatrixAssembliesFlowField.Corrector.Update();
                }
            }

            if (SolverConf.Control.PhysicsMode == PhysicsMode.LowMach)
            {
                // For Low-Mach flows the corrector is never constant
                // due to the density in the divergence operator.
                MatrixAssembliesFlowField.Corrector.Update();
            }

            // Predictor
            // =========

            for (int comp = 0; comp < SolverConf.SpatialDimension; comp++)
            {
                SIMPLESolver Predictor;

                VariableDensitySIMPLEControl varDensConf = SolverConf.Control as VariableDensitySIMPLEControl;
                Predictor = new VariableDensitySolverPredictor(
                    SolverConf,
                    SolverConf.Control.PredictorSolverFactory(),
                    WorkingSetMatrices.Rho.Matrix,
                    MatrixAssembliesFlowField.Predictor[comp],
                    MatrixAssembliesFlowField.PredictorApprox[comp],
                    OperatorsFlowField.PressureGradient,
                    WorkingSet.Pressure,
                    MatrixAssembliesFlowField.ViscSplit,
                    OperatorsFlowField.BuoyantForce,
                    WorkingSet.Velocity,
                    this.GetScalarField(),
                    varDensConf.EoS,
                    BDF);

                Predictor.Solve(WorkingSet.Velocity_Intrmed[comp].CoordinateVector, dt, comp);



                Predictor.Dispose();
            }

            // Corrector
            // =========

            if ((SIMPLEStatus.SIMPLEStepNoTotal == 1) || UpdateApproximations)
            {
                if (Corrector != null)
                {
                    Corrector.Dispose();
                }

                Corrector = this.GetCorrectorSolver();
            }
            Corrector.Solve(WorkingSet.Pressure_Correction.CoordinateVector, dt);

            // Update flow field variables
            // ===========================

            SIMPLEStepUtils.UpdateFlowFieldVariables(dt, SolverConf, OperatorsFlowField.PressureGradient, WorkingSet, BDF, MatrixAssembliesFlowField.PredictorApproxInv);
            if (WorkingSet.DivAfter != null)
            {
                WorkingSet.DivAfter.Clear();
                SolverUtils.CalculateMassDefect_Divergence(OperatorsFlowField.DivergenceConti, WorkingSet.Velocity.Current, WorkingSet.DivAfter);
            }

            // Calculate residuals flow field
            // ==============================

            ResLogger.ComputeL2Norm(WorkingSet.Pressure_Correction, "p'");
            ResLogger.ComputeL2Norm(WorkingSet.VelRes);
        }
예제 #10
0
 /// <summary>
 /// One SIMPLE iteration for low Mach number flows.
 /// </summary>
 /// <param name="SIMPLEStatus"></param>
 /// <param name="dt"></param>
 /// <param name="ResLogger"></param>
 public abstract void OverallIteration(ref SIMPLEStepStatus SIMPLEStatus, double dt, ResidualLogger ResLogger);
예제 #11
0
        /// <summary>
        /// One SIMPLE iteration for incompressible flows.
        /// </summary>
        /// <param name="SIMPLEStatus"></param>
        /// <param name="dt"></param>
        /// <param name="ResLogger"></param>
        public void OverallIteration(ref SIMPLEStepStatus SIMPLEStatus, double dt, ResidualLogger ResLogger)
        {
            using (new FuncTrace()) {
                //Update SIMPLE operators (first!) and matrix assemblies (second!)
                //================================================================

                for (int d = 0; d < m_SolverConf.SpatialDimension; d++)
                {
                    m_IncompressibleOperators.Convection[d].Update();
                    m_IncompressibleMatrixAssemblies.Predictor[d].Update();
                }

                //Determination whether approximation of predictor needs to be updated
                bool UpdatePredictorApprox;
                bool SetPredictorApproxAsConstant = false;
                switch (m_SolverConf.Control.PredictorApproximation)
                {
                case PredictorApproximations.Identity:
                case PredictorApproximations.Identity_IP1:
                    // For unsteady cases the approximation is
                    // gamma * dt / (beta_0 + gamma * dt) * I,
                    // where gamma and beta_0 might not be constant for the first time steps
                    // depending on the current BDF order.
                    if (!m_IncompressibleMatrixAssemblies.PredictorApprox.IsConstant && (SIMPLEStatus.SIMPLEStepNo == 1))
                    {
                        if (m_SolverConf.BDFOrder < m_SolverConf.Control.TimeOrder)
                        {
                            UpdatePredictorApprox = true;
                        }
                        else if (m_SolverConf.BDFOrder == m_SolverConf.Control.TimeOrder)
                        {
                            UpdatePredictorApprox        = true;
                            SetPredictorApproxAsConstant = true;
                        }
                        else
                        {
                            throw new ApplicationException("Should not happen.");
                        }
                    }
                    else
                    {
                        UpdatePredictorApprox = false;
                    }
                    break;

                case PredictorApproximations.Diagonal:
                case PredictorApproximations.BlockDiagonal:
                    UpdatePredictorApprox = (!m_IncompressibleMatrixAssemblies.PredictorApprox.IsConstant &&
                                             ((SIMPLEStatus.SIMPLEStepNo - 1) % m_SolverConf.Control.PredictorApproximationUpdateCycle == 0)) ? true : false;
                    break;

                default:
                    throw new NotImplementedException();
                }

                if (UpdatePredictorApprox)
                {
                    m_IncompressibleMatrixAssemblies.PredictorApprox.Update();
                    m_IncompressibleMatrixAssemblies.PredictorApproxInv.Update();
                    m_IncompressibleMatrixAssemblies.Corrector.Update();
                    if (SetPredictorApproxAsConstant)
                    {
                        m_IncompressibleMatrixAssemblies.PredictorApprox.IsConstant    = true;
                        m_IncompressibleMatrixAssemblies.PredictorApproxInv.IsConstant = true;
                        m_IncompressibleMatrixAssemblies.Corrector.IsConstant          = true;
                    }
                }

                //Predictor
                //=========

                SIMPLESolver Predictor = new SolverPredictor(
                    m_SolverConf,
                    m_SolverConf.Control.PredictorSolverFactory(),
                    m_IncompressibleMatrixAssemblies.Predictor,
                    m_IncompressibleMatrixAssemblies.PredictorApprox,
                    m_IncompressibleOperators.PressureGradient,
                    m_BDF,
                    m_WorkingSet.Velocity,
                    m_WorkingSet.Pressure);

                for (int comp = 0; comp < m_SolverConf.SpatialDimension; comp++)
                {
                    Predictor.Solve(m_WorkingSet.Velocity_Intrmed[comp].CoordinateVector, dt, comp);
                }

                Predictor.Dispose();

                //Corrector
                //=========

                if ((SIMPLEStatus.SIMPLEStepNoTotal == 1) || UpdatePredictorApprox)
                {
                    if (m_Corrector != null)
                    {
                        m_Corrector.Dispose();
                    }

                    m_Corrector = new SolverCorrector(
                        m_SolverConf, m_SolverConf.Control.CorrectorSolverFactory(),
                        m_IncompressibleMatrixAssemblies.Corrector, m_IncompressibleOperators.VelocityDivergence,
                        m_BDF, m_WorkingSet.Velocity_Intrmed, m_WorkingSet.DivB4,
                        m_IncompressibleOperators.PressureStabilization, m_WorkingSet.Pressure);
                }

                m_Corrector.Solve(m_WorkingSet.Pressure_Correction.CoordinateVector, dt);

                //Update variables
                //================

                SIMPLEStepUtils.UpdateFlowFieldVariables(dt, m_SolverConf, m_IncompressibleOperators.PressureGradient, m_WorkingSet, m_BDF, m_IncompressibleMatrixAssemblies.PredictorApproxInv);
                if (m_WorkingSet.DivAfter != null)
                {
                    m_WorkingSet.DivAfter.Clear();
                    SolverUtils.CalculateMassDefect_Divergence(m_IncompressibleOperators.VelocityDivergence, m_WorkingSet.Velocity.Current, m_WorkingSet.DivAfter);
                }

                //Calculate residuals
                //===================

                ResLogger.ComputeL2Norm(m_WorkingSet.Pressure_Correction, "p'");
                ResLogger.ComputeL2Norm(m_WorkingSet.VelRes);

                //Check convergence
                //=================

                if (ResLogger.Residuals["L2Norm p'"] < m_SolverConf.Control.L2NormPressureCorrection &&
                    ResLogger.Residuals["L2Norm u_res"] < m_SolverConf.Control.L2NormVelocityResidual &&
                    ResLogger.Residuals["L2Norm v_res"] < m_SolverConf.Control.L2NormVelocityResidual)
                {
                    if (m_SolverConf.SpatialDimension == 2)
                    {
                        SIMPLEStatus.IsConverged = true;
                    }
                    else if (ResLogger.Residuals["L2Norm w_res"] < m_SolverConf.Control.L2NormVelocityResidual)
                    {
                        SIMPLEStatus.IsConverged = true;
                    }
                }

                //Set SIMPLEStatus
                //================

                if (m_SolverConf.Control.MaxNoSIMPLEsteps == SIMPLEStatus.SIMPLEStepNo)
                {
                    SIMPLEStatus.TerminateSIMPLE = true;
                }

                if ((m_SolverConf.Control.Algorithm == SolutionAlgorithms.Steady_SIMPLE) && (SIMPLEStatus.SIMPLEStepNo % m_SolverConf.Control.SavePeriodSIMPLE == 0))
                {
                    SIMPLEStatus.SaveStep = true;
                }
            }
        }