/// <summary> /// Sets level-set and solution at time (<paramref name="time"/> + <paramref name="dt"/>). /// </summary> double DelUpdateLevelset(DGField[] CurrentState, double time, double dt, double UnderRelax, bool _incremental) { // new time double t = time + dt; // project new level-set double s = 1.0; LevSet.ProjectField((x, y) => - (x - s * t).Pow2() - y.Pow2() + (2.4).Pow2()); LsTrk.UpdateTracker(incremental: _incremental); LsTrk.PushStacks(); // exact solution for new timestep uXEx.GetSpeciesShadowField("A").ProjectField((x, y) => x + alpha_A * t); uXEx.GetSpeciesShadowField("B").ProjectField((x, y) => x + alpha_B * t); // uX.Clear(); //uX.Acc(1.0, uXEx); // single-phase-properties u.Clear(); u.ProjectField(NonVectorizedScalarFunction.Vectorize(uEx, t)); Grad_u.Clear(); Grad_u.Gradient(1.0, u); MagGrad_u.Clear(); MagGrad_u.ProjectFunction(1.0, (double[] X, double[] U, int jCell) => Math.Sqrt(U[0].Pow2() + U[1].Pow2()), new Foundation.Quadrature.CellQuadratureScheme(), Grad_u.ToArray()); // return level-set residual return(0.0); }
/// <summary> /// Log energy for Orr-Sommerfeld problem. /// </summary> void LogEnergyOrrSommerfeld(int TimestepNo, double phystime, double dt) { Energy.Clear(); Energy.ProjectFunction( 1.0, (X, U, cell) => (1.0 - X[1] * X[1] - U[0]) * (1.0 - X[1] * X[1] - U[0]) + U[1] * U[1], null, WorkingSet.Velocity.Current[0], WorkingSet.Velocity.Current[1]); EnergyIntegral = Energy.IntegralOver(null); omega = 1 / (2 * (phystime + dt)) * Math.Log(EnergyIntegral / Energy_t0); if (base.MPIRank == 0) { Log_Energy.WriteLine(); Log_Energy.Write("{0}\t{1}\t{2}", (phystime + dt).ToString("0.000", NumberFormatInfo.InvariantInfo), EnergyIntegral.ToString("0.0000000000E+00", NumberFormatInfo.InvariantInfo), omega.ToString("0.000000E+00", NumberFormatInfo.InvariantInfo)); Log_Energy.Flush(); if (TimestepNo == base.Control.NoOfTimesteps) { Log_Energy.Close(); } } }
/// <summary> /// Initialize logging of energy for Orr-Sommerfeld problem /// </summary> void InitLogEnergyOrrSommerfeld() { Energy = new SinglePhaseField(new Basis(base.GridData, 20)); if (base.MPIRank == 0) { Log_Energy = base.DatabaseDriver.FsDriver.GetNewLog("PerturbationEnergy", CurrentSessionInfo.ID); } Energy.Clear(); Energy.ProjectFunction( 1.0, (X, U, cell) => (1.0 - X[1] * X[1] - U[0]) * (1.0 - X[1] * X[1] - U[0]) + U[1] * U[1], null, WorkingSet.Velocity.Current[0], WorkingSet.Velocity.Current[1]); Energy_t0 = Energy.IntegralOver(null); if (base.MPIRank == 0) { Log_Energy.Write("Time\tPerturbationEnergy\tOmega"); Log_Energy.WriteLine(); Log_Energy.Write("{0}\t{1}\t{2}", (0.0).ToString("0.000", NumberFormatInfo.InvariantInfo), Energy_t0.ToString("0.0000000000E+00", NumberFormatInfo.InvariantInfo), (2.234976E-03).ToString("0.000000E+00", NumberFormatInfo.InvariantInfo)); Log_Energy.Flush(); } if (base.MPIRank == 0) { Console.WriteLine("E(t0) = " + Energy_t0); } }
/// <summary> /// [LowMach] Summand of all time steps for scalar variables, which are constant in space. /// Used for time derivative of thermodynamic pressure in Low-Mach flows. /// </summary> /// <param name="dt"></param> /// <param name="BDFOrder"></param> /// <param name="Scalar"></param> /// <returns> /// Summand of all time steps of <paramref name="Scalar"/>. /// </returns> //public double ComputeSummandScalarHistory(double dt, int BDFOrder, ScalarFieldHistory<SinglePhaseField> Scalar) { // double Summand = 0.0; // for (int alpha = 0; alpha <= BDFOrder; alpha++) // Summand += beta[BDFOrder - 1][alpha] * Scalar[1 - alpha].GetMeanValue(0); // Summand *= 1.0 / (gamma[BDFOrder - 1] * dt); // return Summand; //} /// <summary> /// [LowMach] Summand of all time steps for density. /// Used for time derivative of density in Corrector for Low-Mach flows. /// </summary> /// <param name="dt"></param> /// <param name="BDFOrder"></param> /// <param name="Temperature"></param> /// <param name="EoS"></param> /// <param name="RhsSummand"></param> public void ComputeDensitySummand(double dt, int BDFOrder, ScalarFieldHistory <SinglePhaseField> Temperature, MaterialLaw EoS, SinglePhaseField RhsSummand) { for (int alpha = 0; alpha <= BDFOrder; alpha++) { RhsSummand.ProjectFunction(beta[BDFOrder - 1][alpha], (X, U, cell) => EoS.GetDensity(U[0]), null, Temperature[1 - alpha]); } RhsSummand.Scale(1.0 / (gamma[BDFOrder - 1] * dt)); }
/// <summary> /// [LowMach] Summand for previous time steps in momentum equation. /// </summary> /// <param name="dt"></param> /// <param name="BDFOrder"></param> /// <param name="Scalar"></param> /// <param name="Velocity"></param> /// <param name="SpatialComponent">Velocity component.</param> /// <param name="EoS"></param> /// <param name="RhsSummand">Accumulator for the result.</param> public void ComputeRhsSummand(double dt, int BDFOrder, ScalarFieldHistory <SinglePhaseField> Scalar, VectorFieldHistory <SinglePhaseField> Velocity, int SpatialComponent, MaterialLaw EoS, SinglePhaseField RhsSummand) { for (int alpha = 1; alpha <= BDFOrder; alpha++) { RhsSummand.ProjectFunction(beta[BDFOrder - 1][alpha], (X, U, cell) => EoS.GetDensity(U[0]) * U[1], null, Scalar[1 - alpha], Velocity[1 - alpha][SpatialComponent]); } RhsSummand.Scale(1.0 / (gamma[BDFOrder - 1] * dt)); }
/// <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); } } }