//bool LevelReminder = false; /// <summary> /// Very primitive refinement indicator, works on a gradient criterion. /// </summary> int LevelIndicator(int j, int CurrentLevel) { double GradMag = MagGrad_u.GetMeanValue(j); int DesiredLevel_j = 0; if (GradMag > 0.6) { DesiredLevel_j = 1; } if (GradMag > 0.81) { DesiredLevel_j = 2; } //if(DesiredLevel_j < CurrentLevel) { // DesiredLevel_j = CurrentLevel; // if(!LevelReminder) { // Console.WriteLine("Reminder: coarsening disabled"); // LevelReminder = true; // } //} return(DesiredLevel_j); }
/// <summary> /// Creates fields that mark the boundary conditions. /// </summary> public static DGField[] BoundaryMark(this IGridData m_gridData) { List <DGField> demo_fields = new List <DGField>(); // mark boundary cells { SinglePhaseField boundary = new SinglePhaseField(new Basis(m_gridData, 0), "AllBndCells"); int[,] Edges = m_gridData.iLogicalEdges.CellIndices; int E = Edges.GetLength(0); for (int ee = 0; ee < E; ee++) { int j = Edges[ee, 0]; if (Edges[ee, 1] < 0) { boundary.SetMeanValue(j, boundary.GetMeanValue(j) + 1); } } demo_fields.Add(boundary); } { DGField[] boundaries = new DGField[m_gridData.EdgeTagNames.Keys.Max() + 1]; foreach (byte edgeTag in m_gridData.EdgeTagNames.Keys) { if (edgeTag != 0) { boundaries[edgeTag] = new SinglePhaseField(new Basis(m_gridData, 0), "Boundary_" + m_gridData.EdgeTagNames[edgeTag]); } } boundaries[0] = new SinglePhaseField(new Basis(m_gridData, 0), "UnspecifiedBoundary"); for (int ii = 0; ii < boundaries.Length; ii++) { if (boundaries[ii] == null) { boundaries[ii] = new SinglePhaseField(new Basis(m_gridData, 0), "notused-" + ii); } } int[,] Edges = m_gridData.iGeomEdges.CellIndices; byte[] EdgeTags = m_gridData.iGeomEdges.EdgeTags; int E = Edges.GetLength(0); for (int ee = 0; ee < E; ee++) { int j = Edges[ee, 0]; if (Edges[ee, 1] < 0) { int tag = EdgeTags[ee]; boundaries[tag].SetMeanValue(j, boundaries[tag].GetMeanValue(j) + 1); } } demo_fields.AddRange(boundaries); } return(demo_fields.ToArray()); }
/// <summary> /// Returns all cells with the respective artificial viscosity value /// if the value is larger than zero /// </summary> /// <param name="gridData">The needed <see cref="GridData"/></param> /// <param name="avField">The artificial visocsity <see cref="SinglePhaseField"/></param> /// <returns> <see cref="MultidimensionalArray"/> /// Lenghts --> [0]: number of points (AV > 0), [1]: 2 /// [1] --> [0]: cellIndex, [2:] AV value /// </returns> public static MultidimensionalArray GetAVMeanValues(GridData gridData, SinglePhaseField avField) { CellMask allCells = CellMask.GetFullMask(gridData); double[] cellIndices = new double[allCells.NoOfItemsLocally]; double[] avValues = new double[allCells.NoOfItemsLocally]; int count = 0; foreach (int cell in allCells.ItemEnum) { double avValue = avField.GetMeanValue(cell); if (avValue > 0.0) { cellIndices[count] = cell; avValues[count] = avValue; count++; } } Array.Resize(ref cellIndices, count); Array.Resize(ref avValues, count); MultidimensionalArray result = MultidimensionalArray.Create(count, 2); result.SetSubVector(cellIndices, new int[] { -1, 0 }); result.SetSubVector(avValues, new int[] { -1, 1 }); return(result); }
//Create an array of Cells from the Accepted CellMask. public static MarchingCell[] BuildInitialAcceptedCells(CellMask Accepted) { int[] AcceptedCells_Indices = Accepted.ItemEnum.ToArray(); int AcceptedCells_Total = AcceptedCells_Indices.Length; MarchingCell[] AcceptedCells = new MarchingCell[AcceptedCells_Total]; for (int i = 0; i < AcceptedCells_Total; ++i) { int jCell = AcceptedCells_Indices[i]; double phi_average = phi.GetMeanValue(jCell); AcceptedCells[i] = new MarchingCell(jCell, phi_average); AcceptedCells[i].Accept(); } return(AcceptedCells); }
//Manufactured solution for T = cos(x*y), Y0 = 0.3 cos(x*y), Y1 = 0.6 cos(x*y), Y2 = 0.1 cos(x*y), u = -cos(x), v = -cos(y), p = sin(x*y). protected override double Source(double[] x, double[] parameters, double[] U) { double x_ = x[0]; double y_ = x[1]; double t_ = phystime; double p0 = ThermodynamicPressure.GetMeanValue(3); //Console.WriteLine(p0); double M1 = MolarMasses[0]; double M2 = MolarMasses[1]; double M3 = MolarMasses[2]; double M4 = MolarMasses[3]; double alpha1 = 0.3; double alpha2 = 0.6; double alpha3 = 0.1; double man1; if (unsteady) { switch (physicsMode) { case PhysicsMode.LowMach: man1 = -1 * (p0 * Math.Pow(Math.Cos(x_ * y_ * t_), -0.2e1) * x_ * y_ * Math.Sin(x_ * y_ * t_) - p0 * Math.Pow(Math.Cos(x_ * y_ * t_), -0.2e1) * Math.Cos(x_ * t_) * y_ * t_ * Math.Sin(x_ * y_ * t_) + p0 / Math.Cos(x_ * y_ * t_) * t_ * Math.Sin(x_ * t_) - p0 * Math.Pow(Math.Cos(x_ * y_ * t_), -0.2e1) * Math.Cos(y_ * t_) * x_ * t_ * Math.Sin(x_ * y_ * t_) + p0 / Math.Cos(x_ * y_ * t_) * t_ * Math.Sin(y_ * t_)); break; case PhysicsMode.Combustion: man1 = 0.0; //TODO break; default: throw new NotImplementedException("should not happen"); } } else { switch (physicsMode) { case PhysicsMode.LowMach: man1 = -1 * (-p0 * Math.Pow(Math.Cos(x_ * y_), -0.2e1) * Math.Cos(x_) * y_ * Math.Sin(x_ * y_) + p0 / Math.Cos(x_ * y_) * Math.Sin(x_) - p0 * Math.Pow(Math.Cos(x_ * y_), -0.2e1) * Math.Cos(y_) * x_ * Math.Sin(x_ * y_) + p0 / Math.Cos(x_ * y_) * Math.Sin(y_)); // conti, momentum and energy break; case PhysicsMode.Combustion: man1 = -1 * (-p0 * Math.Pow(Math.Cos(x_ * y_), -0.2e1) / (alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4) * Math.Cos(x_) * y_ * Math.Sin(x_ * y_) + p0 / Math.Cos(x_ * y_) * Math.Pow(alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4, -0.2e1) * Math.Cos(x_) * (-alpha1 * y_ * Math.Sin(x_ * y_) / M1 - alpha2 * y_ * Math.Sin(x_ * y_) / M2 - alpha3 * y_ * Math.Sin(x_ * y_) / M3 + (alpha1 * y_ * Math.Sin(x_ * y_) + alpha2 * y_ * Math.Sin(x_ * y_) + alpha3 * y_ * Math.Sin(x_ * y_)) / M4) + p0 / Math.Cos(x_ * y_) / (alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4) * Math.Sin(x_) - p0 * Math.Pow(Math.Cos(x_ * y_), -0.2e1) / (alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4) * Math.Cos(y_) * x_ * Math.Sin(x_ * y_) + p0 / Math.Cos(x_ * y_) * Math.Pow(alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4, -0.2e1) * Math.Cos(y_) * (-alpha1 * x_ * Math.Sin(x_ * y_) / M1 - alpha2 * x_ * Math.Sin(x_ * y_) / M2 - alpha3 * x_ * Math.Sin(x_ * y_) / M3 + (alpha1 * x_ * Math.Sin(x_ * y_) + alpha2 * x_ * Math.Sin(x_ * y_) + alpha3 * x_ * Math.Sin(x_ * y_)) / M4) + p0 / Math.Cos(x_ * y_) / (alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4) * Math.Sin(y_)); // conti, momentum, energy and species break; default: throw new NotImplementedException("should not happen"); } } return(man1); }
/// <summary> /// Creates a continuous version of a DG level set field /// </summary> /// <param name="DGLevelSet">The input DG level set field</param> /// <param name="jCells">Local cell indices</param> /// <returns>A continuous level set <see cref="SinglePhaseField"/> with one order higher than the input</returns> public static SinglePhaseField ContinuousLevelSet(SinglePhaseField DGLevelSet, double[] jCells) { Console.WriteLine(String.Format("Continuity projection of field {0} started...", DGLevelSet.Identification)); // Init IGridData gridData = DGLevelSet.GridDat; SinglePhaseField continuousLevelSet = new SinglePhaseField(new Basis(gridData, DGLevelSet.Basis.Degree + 1), DGLevelSet.Identification + "_cont"); // Create narrow band List <int> allNeighbours = new List <int>(); foreach (int cell in jCells) { gridData.GetCellNeighbours(cell, GetCellNeighbours_Mode.ViaVertices, out int[] cellNeighbours, out int[] connectingEntities); allNeighbours.Add(cell); allNeighbours.AddRange(cellNeighbours); } List <int> narrowBandCells = allNeighbours.Distinct().ToList(); BitArray bitMaskNarrowBand = new BitArray(gridData.iLogicalCells.NoOfLocalUpdatedCells); foreach (int cell in narrowBandCells) { bitMaskNarrowBand[cell] = true; } CellMask narrowBand = new CellMask(gridData, bitMaskNarrowBand); // Create positive mask BitArray bitMaskPos = new BitArray(gridData.iLogicalCells.NoOfLocalUpdatedCells); for (int i = 0; i < gridData.iLogicalCells.NoOfLocalUpdatedCells; i++) { if (DGLevelSet.GetMeanValue(i) > 0 && !bitMaskNarrowBand[i]) { bitMaskPos[i] = true; } } CellMask posMask = new CellMask(gridData, bitMaskPos); // Continuity projection ContinuityProjection continuityProjection = new ContinuityProjection(continuousLevelSet.Basis, DGLevelSet.Basis, gridData, ContinuityProjectionOption.ConstrainedDG); continuityProjection.MakeContinuous(DGLevelSet, continuousLevelSet, narrowBand, posMask); Console.WriteLine("finished"); return(continuousLevelSet); }
/// <summary> /// Very primitive refinement indicator, works on a gradient criterion. /// </summary> int LevelInicator(int j, int CurrentLevel) { double GradMag = MagGrad_u.GetMeanValue(j); int DesiredLevel_j = 0; if (GradMag > 0.6) { DesiredLevel_j = 1; } if (GradMag > 0.81) { DesiredLevel_j = 2; } return(DesiredLevel_j); }
public void AvgInit(SinglePhaseField Phi, CellMask _Accepted) { int J = this.GridDat.Cells.NoOfCells; double[] PhiAvg; if (m_PhiAvg == null) { PhiAvg = new double[J]; m_PhiAvg = PhiAvg; } else { PhiAvg = m_PhiAvg; } foreach (int jCell in _Accepted.ItemEnum) { PhiAvg[jCell] = Phi.GetMeanValue(jCell); } }
/// <summary> /// Calculates the Torque around the center of mass /// </summary> /// <param name="U"></param> /// <param name="P"></param> /// <param name="momentFittingVariant"></param> /// <param name="muA"></param> /// <param name="particleRadius"></param> /// <returns></returns> static public void GetCellValues(VectorField <XDGField> U, XDGField P, double muA, double particleRadius, SinglePhaseField P_atIB, SinglePhaseField gradU_atIB, SinglePhaseField gradUT_atIB) { var LsTrk = U[0].Basis.Tracker; int D = LsTrk.GridDat.SpatialDimension; var UA = U.Select(u => u.GetSpeciesShadowField("A")).ToArray(); if (D > 2) { throw new NotImplementedException("Currently only 2D cases supported"); } int RequiredOrder = U[0].Basis.Degree * 3 + 2; //if (RequiredOrder > agg.HMForder) // throw new ArgumentException(); Console.WriteLine("Cell values calculated by: {0}, order = {1}", LsTrk.CutCellQuadratureType, RequiredOrder); ConventionalDGField pA = null; double circumference = new double(); pA = P.GetSpeciesShadowField("A"); for (int n = 0; n < 4; n++) { ScalarFunctionEx ErrFunc_CellVal = delegate(int j0, int Len, NodeSet Ns, MultidimensionalArray result) { int K = result.GetLength(1); // No nof Nodes MultidimensionalArray Grad_UARes = MultidimensionalArray.Create(Len, K, D, D);; MultidimensionalArray pARes = MultidimensionalArray.Create(Len, K); // Evaluate tangential velocity to level-set surface var Normals = LsTrk.DataHistories[0].Current.GetLevelSetNormals(Ns, j0, Len); for (int i = 0; i < D; i++) { UA[i].EvaluateGradient(j0, Len, Ns, Grad_UARes.ExtractSubArrayShallow(-1, -1, i, -1)); } pA.Evaluate(j0, Len, Ns, pARes); for (int j = 0; j < Len; j++) { for (int k = 0; k < K; k++) { double acc = 0.0; double acc2 = 0.0; switch (n) { case 0: // Pressure part acc += pARes[j, k] * Normals[j, k, 0]; acc *= -Normals[j, k, 1] * particleRadius; acc2 += pARes[j, k] * Normals[j, k, 1]; acc2 *= Normals[j, k, 0] * particleRadius; result[j, k] = acc + acc2; break; case 1: // GradU part acc -= (1 * muA) * Grad_UARes[j, k, 0, 0] * Normals[j, k, 0]; // Attention was 2 times acc -= (muA) * Grad_UARes[j, k, 0, 1] * Normals[j, k, 1]; acc *= -Normals[j, k, 1] * particleRadius; acc2 -= (1 * muA) * Grad_UARes[j, k, 1, 1] * Normals[j, k, 1]; acc2 -= (muA) * Grad_UARes[j, k, 1, 0] * Normals[j, k, 0]; acc2 *= Normals[j, k, 0] * particleRadius; result[j, k] = acc + acc2; break; case 2: // GradU_T part acc -= (1 * muA) * Grad_UARes[j, k, 0, 0] * Normals[j, k, 0]; // Attention was 2 times acc -= (muA) * Grad_UARes[j, k, 1, 0] * Normals[j, k, 1]; acc *= -Normals[j, k, 1] * particleRadius; acc2 -= (1 * muA) * Grad_UARes[j, k, 1, 1] * Normals[j, k, 1]; // Attention was 2 times acc2 -= (muA) * Grad_UARes[j, k, 0, 1] * Normals[j, k, 0]; acc2 *= Normals[j, k, 0] * particleRadius; result[j, k] = acc + acc2; break; case 3: // Standardization with radians result[j, k] = 1; break; default: throw new NotImplementedException(); } } } }; var SchemeHelper = LsTrk.GetXDGSpaceMetrics(new[] { LsTrk.GetSpeciesId("A") }, RequiredOrder, 1).XQuadSchemeHelper; // new XQuadSchemeHelper(LsTrk, momentFittingVariant, ); CellQuadratureScheme cqs = SchemeHelper.GetLevelSetquadScheme(0, LsTrk.Regions.GetCutCellMask()); CellQuadrature.GetQuadrature(new int[] { 1 }, LsTrk.GridDat, cqs.Compile(LsTrk.GridDat, RequiredOrder), delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) { ErrFunc_CellVal(i0, Length, QR.Nodes, EvalResult.ExtractSubArrayShallow(-1, -1, 0)); }, delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { for (int i = 0; i < Length; i++) { switch (n) { case 0: P_atIB.SetMeanValue(i0, ResultsOfIntegration[i, 0]); break; case 1: gradU_atIB.SetMeanValue(i0, ResultsOfIntegration[i, 0]); break; case 2: gradUT_atIB.SetMeanValue(i0, ResultsOfIntegration[i, 0]); break; case 3: circumference += ResultsOfIntegration[i, 0]; P_atIB.SetMeanValue(i0, P_atIB.GetMeanValue(i0) / ResultsOfIntegration[i, 0]); gradU_atIB.SetMeanValue(i0, gradU_atIB.GetMeanValue(i0) / ResultsOfIntegration[i, 0]); gradUT_atIB.SetMeanValue(i0, gradUT_atIB.GetMeanValue(i0) / ResultsOfIntegration[i, 0]); break; default: throw new NotImplementedException(); } } } ).Execute(); } Console.WriteLine("Circle circumference: " + circumference); }
/// <summary> /// Extension velocity on un-cut cells. /// </summary> /// <param name="Phi">Input; a signed-distance field.</param> /// <param name="Domain">Cells in which the extension velocity should be computed.</param> /// <param name="cut">Cells in which a value for the extension property is given, must be /// disjoint from and share a boundary with <paramref name="Domain"/>. /// </param> /// <param name="ExtProperty"> /// Input/Output: on cells in <paramref name="cut"/>, valid values for the extension property, /// i.e. boundary values for the extension problem. /// On exit, the result of the marching algorithm is stored in the <paramref name="Domain"/>-cells. /// Multiple extension properties can be constructed at once. /// </param> /// <param name="ExtPropertyMin"> /// Input/Output: Helper array to check the minimum/maximum principle of the extension velocity problem /// - 1st index: extension property index /// - 2nd index: cell index /// On entry, the minimum values for cells in <paramref name="cut"/> must contain valid entries. /// </param> /// <param name="ExtPropertyMax"> /// Analogous to <paramref name="ExtPropertyMin"/>. /// </param> /// <param name="GradPhi"> /// Helper variable to compute the gradient values of <paramref name="Phi"/>. /// </param> public void ConstructExtension(SinglePhaseField Phi, CellMask Domain, CellMask cut, ConventionalDGField[] ExtProperty, double[][] ExtPropertyMin, double[][] ExtPropertyMax, VectorField <SinglePhaseField> GradPhi, int TimestepNo, bool plotMarchingSteps = false) // { using (new FuncTrace()) { Tracer.InstrumentationSwitch = false; // lots of tracing on calls acting on singe cells causes massive overhead (up to 5x slower). Stpw_total.Start(); // check args and init // =================== //ExtVelSolver extVelSlv = null; ExtVelSolver_Geometric extVelSlv = null; if (ExtProperty != null) { if (ExtProperty.Length != ExtPropertyMin.Length) { throw new ArgumentException(); } if (ExtProperty.Length != ExtPropertyMax.Length) { throw new ArgumentException(); } //extVelSlv = new ExtVelSolver(ExtProperty[0].Basis); extVelSlv = new ExtVelSolver_Geometric(ExtProperty[0].Basis); } BitArray Accepted_Mutuable = cut.GetBitMask().CloneAs(); int J = this.GridDat.Cells.NoOfCells; int D = this.GridDat.SpatialDimension; int N = this.LevelSetBasis.Length; int[] DomainCellIndices = Domain.ItemEnum.ToArray(); double[] PhiAvg = new double[DomainCellIndices.Length]; { int L = DomainCellIndices.Length; for (int jSub = 0; jSub < L; jSub++) { int jCell = DomainCellIndices[jSub]; PhiAvg[jSub] = Phi.GetMeanValue(jCell); } Array.Sort(PhiAvg, DomainCellIndices); } if (this.GridDat.MpiSize > 1) { throw new NotSupportedException("Currently not MPI parallel."); } int[] PosDomain, NegDomain; { int median = 0; for (; median < DomainCellIndices.Length; median++) { if (PhiAvg[median] >= 0) { break; } } NegDomain = new int[median]; for (int i = 0; i < median; i++) { NegDomain[i] = DomainCellIndices[median - i - 1]; } PosDomain = new int[DomainCellIndices.Length - median]; Array.Copy(DomainCellIndices, median, PosDomain, 0, PosDomain.Length); Debug.Assert(PosDomain.Length + NegDomain.Length == DomainCellIndices.Length); } if (plotMarchingSteps) { this.plotter.setup(new DGField[] { Phi, ExtProperty[0], ExtProperty[1] }, TimestepNo); this.plotter.plotstep(Accepted_Mutuable); } // perform marching... // =================== // marching loop.. for (int iMinusPlus = -1; iMinusPlus <= 1; iMinusPlus += 2) { double _sign = iMinusPlus; int[] _Domain; switch (iMinusPlus) { case -1: _Domain = NegDomain; break; case +1: _Domain = PosDomain; break; default: throw new Exception(); } for (int iSub = 0; iSub < _Domain.Length; iSub++) { CellMask Accepted = new CellMask(this.GridDat, Accepted_Mutuable); int jCellAccpt = _Domain[iSub]; //this.Stpw_gradientEval.Start(); //gradModule.GradientUpdate(jCellAccpt, Acceped_Mutuable, Phi, GradPhi); //this.Stpw_gradientEval.Stop(); // solve for the extension properties // ---------------------------------- if (ExtProperty != null) { int[] Neighb, dummy33; GridDat.GetCellNeighbours(jCellAccpt, GetCellNeighbours_Mode.ViaEdges, out Neighb, out dummy33); // solve for each component seperately for (int iComp = 0; iComp < ExtProperty.Length; iComp++) { ExtPropertyMax[iComp][jCellAccpt] = -double.MaxValue; ExtPropertyMin[iComp][jCellAccpt] = double.MaxValue; foreach (int jNeig in Neighb) { if (Accepted_Mutuable[jNeig]) { ExtPropertyMax[iComp][jCellAccpt] = Math.Max(ExtPropertyMax[iComp][jCellAccpt], ExtPropertyMax[iComp][jNeig]); ExtPropertyMin[iComp][jCellAccpt] = Math.Min(ExtPropertyMin[iComp][jCellAccpt], ExtPropertyMin[iComp][jNeig]); } } this.Stpw_extVelSolver.Start(); //extVelSlv.ExtVelSolve_Far(Phi, GradPhi, ExtProperty[iComp], ref ExtPropertyMin[iComp][jCellAccpt], ref ExtPropertyMax[iComp][jCellAccpt], jCellAccpt, Accepted, _sign); extVelSlv.ExtVelSolve_Geometric(Phi, ExtProperty[iComp], Accepted_Mutuable, jCellAccpt, _sign); this.Stpw_extVelSolver.Start(); } } Accepted_Mutuable[jCellAccpt] = true; if (plotMarchingSteps) { this.plotter.plotstep(Accepted_Mutuable); } } } Tracer.InstrumentationSwitch = true; Stpw_total.Stop(); } }
/// <summary> /// Reinit on un-cut cells. /// </summary> /// <param name="Phi">The level set</param> /// <param name="ReInitSpecies">Cell mask wich is to be reinitialized</param> /// <param name="sign">Sign of the level set for this <paramref name="ReInitSpecies"/></param> /// <param name="_Accepted">CellMask which is taken as boundray values</param> /// <param name="GradPhi">LEvel Set gradient</param> /// <param name="callBack">A delegate, which might be called after the execution of the reinitialization</param> public void Reinitialize(SinglePhaseField Phi, CellMask ReInitSpecies, double sign, CellMask _Accepted, //ConventionalDGField[] ExtProperty, double[][] ExtPropertyMin, double[][] ExtPropertyMax, VectorField <SinglePhaseField> GradPhi, Action <int> callBack) // { using (new FuncTrace()) { Tracer.InstrumentationSwitch = false; // lots of tracing on calls acting on singe cells causes massive overhead (up to 5x slower). Stpw_total.Start(); SinglePhaseField DiffusionCoeff = new SinglePhaseField(new Basis(this.GridDat, 1), "DiffusionCoeff"); // check args and init // =================== /* * ExtVelSolver extVelSlv = null; * if(ExtProperty != null) { * if(ExtProperty.Length != ExtPropertyMin.Length) * throw new ArgumentException(); * if(ExtProperty.Length != ExtPropertyMax.Length) * throw new ArgumentException(); * * extVelSlv = new ExtVelSolver(ExtProperty[0].Basis); * } */ BitArray Acceped_Mutuable = _Accepted.GetBitMask().CloneAs(); BitArray Trial_Mutuable = ((_Accepted.AllNeighbourCells().Intersect(ReInitSpecies)).Except(_Accepted)).GetBitMask().CloneAs(); BitArray Recalc_Mutuable = Trial_Mutuable.CloneAs(); BitArray PosSpecies_Bitmask = ReInitSpecies.GetBitMask(); int J = this.GridDat.Cells.NoOfCells; int D = this.GridDat.SpatialDimension; int N = this.LevelSetBasis.Length; double _sign = sign >= 0 ? 1.0 : -1.0; double[] PhiAvg = m_PhiAvg; if (PhiAvg == null) { throw new ApplicationException(); } foreach (int jCell in _Accepted.ItemEnum) { PhiAvg[jCell] = Phi.GetMeanValue(jCell); } int NoOfNew; { var Neu = ReInitSpecies.Except(_Accepted); NoOfNew = Neu.NoOfItemsLocally; Phi.Clear(Neu); Phi.AccConstant(_sign, Neu); foreach (int jCell in Neu.ItemEnum) { PhiAvg[jCell] = 1.0e10; } } if (this.GridDat.MpiSize > 1) { throw new NotSupportedException("Currently not MPI parallel."); } for (int d = 0; d < this.GridDat.SpatialDimension; d++) { if (!GradPhi[d].Basis.Equals(Phi.Basis)) { throw new ArgumentException("Level-set and level-set gradient field should have the same DG basis."); // ein grad niedriger wrürde auch genügen... } } // perform marching... // =================== // update gradient for cut-cells GradPhi.Clear(_Accepted); GradPhi.Gradient(1.0, Phi, _Accepted); // marching loop../ int cnt = 0; while (true) { cnt++; CellMask Recalc = new CellMask(this.GridDat, Recalc_Mutuable); CellMask Accepted = new CellMask(this.GridDat, Acceped_Mutuable); CellMask Trial = new CellMask(this.GridDat, Trial_Mutuable); int NoOfTrial = Trial.NoOfItemsLocally; int NoOfAccpt = Accepted.NoOfItemsLocally; int NoOfRcalc = Recalc.NoOfItemsLocally; if (Trial.NoOfItemsLocally <= 0) { //Ploti(Recalc, Accepted, Trial, Phi, Phi_gradient, optEikonalOut, cnt); break; } // Local solver for all 'Recalc'-cells // -------------------------------------- if (Recalc.NoOfItemsLocally > 0) { this.LocalSolve(Accepted, Recalc, Phi, GradPhi, _sign, DiffusionCoeff); } // find the next cell to accept // ---------------------------- // get mean value in all cells foreach (int jCell in Recalc.ItemEnum) { PhiAvg[jCell] = Phi.GetMeanValue(jCell); Recalc_Mutuable[jCell] = false; } //Ploti(Recalc, Accepted, Trial, Phi, Phi_gradient, optEikonalOut, cnt); // find trial-cell with minimum average value // this should be done with heap-sort (see fast-marching algorithm) int jCellAccpt = int.MaxValue; double TrialMin = double.MaxValue; foreach (int jCell in Trial.ItemEnum) { if (PhiAvg[jCell] * _sign < TrialMin) { TrialMin = PhiAvg[jCell] * _sign; jCellAccpt = jCell; } } if (callBack != null) { callBack(cnt); } /* * // update the gradient * // ------------------- * * this.Stpw_gradientEval.Start(); * gradModule.GradientUpdate(jCellAccpt, Acceped_Mutuable, Phi, GradPhi); * this.Stpw_gradientEval.Stop(); * * /* * // solve for the extension properties * // ---------------------------------- * * if(ExtProperty != null) { * int[] Neight, dummy33; * GridDat.Cells.GetCellNeighbours(jCellAccpt, GridData.CellData.GetCellNeighbours_Mode.ViaEdges, out Neight, out dummy33); * * for(int iComp = 0; iComp < ExtProperty.Length; iComp++) { * * ExtPropertyMax[iComp][jCellAccpt] = -double.MaxValue; * ExtPropertyMin[iComp][jCellAccpt] = double.MaxValue; * * foreach(int jNeig in Neight) { * if(Acceped_Mutuable[jNeig]) { * ExtPropertyMax[iComp][jCellAccpt] = Math.Max(ExtPropertyMax[iComp][jCellAccpt], ExtPropertyMax[iComp][jNeig]); * ExtPropertyMin[iComp][jCellAccpt] = Math.Min(ExtPropertyMin[iComp][jCellAccpt], ExtPropertyMin[iComp][jNeig]); * } * } * * this.Stpw_extVelSolver.Start(); * extVelSlv.ExtVelSolve_Far(Phi, GradPhi, ExtProperty[iComp], ref ExtPropertyMin[iComp][jCellAccpt], ref ExtPropertyMax[iComp][jCellAccpt], jCellAccpt, Accepted, _sign); * this.Stpw_extVelSolver.Stop(); * } * } * /* * { * int[] Neight, dummy33; * GridDat.Cells.GetCellNeighbours(jCellAccpt, GridData.CellData.GetCellNeighbours_Mode.ViaEdges, out Neight, out dummy33); * foreach(int jNeig in Neight) { * if(Acceped_Mutuable[jNeig]) { * plotDependencyArrow(cnt, jCellAccpt, jNeig); * } * } * } */ // the mimium is moved to accepted // ------------------------------- Acceped_Mutuable[jCellAccpt] = true; Trial_Mutuable[jCellAccpt] = false; Recalc_Mutuable[jCellAccpt] = false; NoOfNew--; // recalc on all neighbours // ------------------------ int[] Neighs, dummy; this.GridDat.GetCellNeighbours(jCellAccpt, GetCellNeighbours_Mode.ViaEdges, out Neighs, out dummy); foreach (int jNeig in Neighs) { if (!Acceped_Mutuable[jNeig] && PosSpecies_Bitmask[jNeig]) { Trial_Mutuable[jNeig] = true; Recalc_Mutuable[jNeig] = true; } } } if (NoOfNew > 0) { throw new ArithmeticException("Unable to perform reinitialization for all requested cells - maybe they are not reachable from the initialy 'accepted' domain?"); } //PlottAlot("dependencies.csv"); Tracer.InstrumentationSwitch = true; Stpw_total.Stop(); } }
//Manufactured solution for T = cos(x*y), Y0 = 0.3 cos(x*y), Y1 = 0.6 cos(x*y), Y2 = 0.1 cos(x*y), u = cos(x*y), v = cos(x*y), p = sin(x*y). protected override double Source(double[] x, double[] parameters, double[] U) { double p0 = ThermodynamicPressure.GetMeanValue(3); double M1 = MolarMasses[0]; double M2 = MolarMasses[1]; double M3 = MolarMasses[2]; double M4 = MolarMasses[3]; double x_ = x[0]; double y_ = x[1]; double alpha1 = 0.3; double alpha2 = 0.6; double alpha3 = 0.1; double[] Coefficients = new double[] { alpha1, alpha2, alpha3 }; double ConvectionTerm; double ViscTerm; double PressureGradientTerm; double BouyancyTerm; double unsteadyTerm = 0.0; double t_ = 0.0; bool unsteady = false; if (unsteady) { if (direction == "x") { switch (physMode) { case PhysicsMode.LowMach: unsteadyTerm = -p0 *Math.Pow(Math.Cos(x_ *y_ *t_), -0.2e1) * Math.Cos(x_ * t_) * x_ * y_ * Math.Sin(x_ * y_ * t_) + p0 / Math.Cos(x_ * y_ * t_) * x_ * Math.Sin(x_ * t_); ConvectionTerm = p0 * Math.Pow(Math.Cos(x_ * y_ * t_), -0.2e1) * Math.Pow(Math.Cos(x_ * t_), 0.2e1) * y_ * t_ * Math.Sin(x_ * y_ * t_) - 0.2e1 * p0 / Math.Cos(x_ * y_ * t_) * Math.Cos(x_ * t_) * t_ * Math.Sin(x_ * t_) + p0 * Math.Pow(Math.Cos(x_ * y_ * t_), -0.2e1) * Math.Cos(x_ * t_) * Math.Cos(y_ * t_) * x_ * t_ * Math.Sin(x_ * y_ * t_) - p0 / Math.Cos(x_ * y_ * t_) * Math.Cos(x_ * t_) * t_ * Math.Sin(y_ * t_); break; case PhysicsMode.Combustion: unsteadyTerm = 0.0; //TODO ConvectionTerm = 0.0; //TODO break; default: throw new NotImplementedException("should not happen"); } ViscTerm = -0.4e1 / 0.3e1 / Reynolds * t_ * t_ * Math.Cos(x_ * t_); PressureGradientTerm = y_ * t_ * Math.Cos(x_ * y_ * t_); BouyancyTerm = 0.0; //OK } else if (direction == "y") { switch (physMode) { case PhysicsMode.LowMach: ConvectionTerm = p0 * Math.Pow(Math.Cos(x_ * y_ * t_), -0.2e1) * Math.Cos(y_ * t_) * Math.Cos(x_ * t_) * y_ * t_ * Math.Sin(x_ * y_ * t_) - p0 / Math.Cos(x_ * y_ * t_) * Math.Cos(y_ * t_) * t_ * Math.Sin(x_ * t_) + p0 * Math.Pow(Math.Cos(x_ * y_ * t_), -0.2e1) * Math.Pow(Math.Cos(y_ * t_), 0.2e1) * x_ * t_ * Math.Sin(x_ * y_ * t_) - 0.2e1 * p0 / Math.Cos(x_ * y_ * t_) * Math.Cos(y_ * t_) * t_ * Math.Sin(y_ * t_); unsteadyTerm = -p0 *Math.Pow(Math.Cos(x_ *y_ *t_), -0.2e1) * Math.Cos(y_ * t_) * x_ * y_ * Math.Sin(x_ * y_ * t_) + p0 / Math.Cos(x_ * y_ * t_) * y_ * Math.Sin(y_ * t_); BouyancyTerm = Math.Pow(Froude, -0.2e1) * p0 / Math.Cos(x_ * y_ * t_); break; case PhysicsMode.Combustion: ConvectionTerm = 0.0; //TODO unsteadyTerm = 0.0; //TODO BouyancyTerm = 0.0; //TODO break; default: throw new NotImplementedException("should not happen"); } ViscTerm = -0.4e1 / 0.3e1 / Reynolds * t_ * t_ * Math.Cos(y_ * t_); PressureGradientTerm = x_ * t_ * Math.Cos(x_ * y_ * t_); } else { throw new ArgumentException("Specified direction not supported"); } } else { if (direction == "x") { switch (physMode) { case PhysicsMode.LowMach: ConvectionTerm = p0 * Math.Pow(Math.Cos(x_ * y_), -0.2e1) * Math.Pow(Math.Cos(x_), 0.2e1) * y_ * Math.Sin(x_ * y_) - 0.2e1 * p0 / Math.Cos(x_ * y_) * Math.Cos(x_) * Math.Sin(x_) + p0 * Math.Pow(Math.Cos(x_ * y_), -0.2e1) * Math.Cos(x_) * Math.Cos(y_) * x_ * Math.Sin(x_ * y_) - p0 / Math.Cos(x_ * y_) * Math.Cos(x_) * Math.Sin(y_); // conti, mom and energy break; case PhysicsMode.Combustion: ConvectionTerm = p0 * Math.Pow(Math.Cos(x_ * y_), -0.2e1) / (alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4) * Math.Pow(Math.Cos(x_), 0.2e1) * y_ * Math.Sin(x_ * y_) - p0 / Math.Cos(x_ * y_) * Math.Pow(alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4, -0.2e1) * Math.Pow(Math.Cos(x_), 0.2e1) * (-alpha1 * y_ * Math.Sin(x_ * y_) / M1 - alpha2 * y_ * Math.Sin(x_ * y_) / M2 - alpha3 * y_ * Math.Sin(x_ * y_) / M3 + (alpha1 * y_ * Math.Sin(x_ * y_) + alpha2 * y_ * Math.Sin(x_ * y_) + alpha3 * y_ * Math.Sin(x_ * y_)) / M4) - 0.2e1 * p0 / Math.Cos(x_ * y_) / (alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4) * Math.Cos(x_) * Math.Sin(x_) + p0 * Math.Pow(Math.Cos(x_ * y_), -0.2e1) / (alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4) * Math.Cos(x_) * Math.Cos(y_) * x_ * Math.Sin(x_ * y_) - p0 / Math.Cos(x_ * y_) * Math.Pow(alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4, -0.2e1) * Math.Cos(x_) * Math.Cos(y_) * (-alpha1 * x_ * Math.Sin(x_ * y_) / M1 - alpha2 * x_ * Math.Sin(x_ * y_) / M2 - alpha3 * x_ * Math.Sin(x_ * y_) / M3 + (alpha1 * x_ * Math.Sin(x_ * y_) + alpha2 * x_ * Math.Sin(x_ * y_) + alpha3 * x_ * Math.Sin(x_ * y_)) / M4) - p0 / Math.Cos(x_ * y_) / (alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4) * Math.Cos(x_) * Math.Sin(y_); break; default: throw new NotImplementedException("should not happen"); } ViscTerm = -0.4e1 / 0.3e1 * Math.Cos(x_) / Reynolds; // TODO? PressureGradientTerm = y_ * Math.Cos(x_ * y_); // OK BouyancyTerm = 0.0; } else if (direction == "y") { switch (physMode) { case PhysicsMode.LowMach: ConvectionTerm = p0 * Math.Pow(Math.Cos(x_ * y_), -0.2e1) * Math.Cos(x_) * Math.Cos(y_) * y_ * Math.Sin(x_ * y_) - p0 / Math.Cos(x_ * y_) * Math.Sin(x_) * Math.Cos(y_) + p0 * Math.Pow(Math.Cos(x_ * y_), -0.2e1) * Math.Pow(Math.Cos(y_), 0.2e1) * x_ * Math.Sin(x_ * y_) - 0.2e1 * p0 / Math.Cos(x_ * y_) * Math.Cos(y_) * Math.Sin(y_); // conti, mom and energy BouyancyTerm = -1 / (Froude * Froude) * p0 / Math.Cos(x_ * y_); // -1/Fr*p0/T, bouyancy term break; case PhysicsMode.Combustion: ConvectionTerm = p0 * Math.Pow(Math.Cos(x_ * y_), -0.2e1) / (alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4) * Math.Cos(y_) * Math.Cos(x_) * y_ * Math.Sin(x_ * y_) - p0 / Math.Cos(x_ * y_) * Math.Pow(alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4, -0.2e1) * Math.Cos(y_) * Math.Cos(x_) * (-alpha1 * y_ * Math.Sin(x_ * y_) / M1 - alpha2 * y_ * Math.Sin(x_ * y_) / M2 - alpha3 * y_ * Math.Sin(x_ * y_) / M3 + (alpha1 * y_ * Math.Sin(x_ * y_) + alpha2 * y_ * Math.Sin(x_ * y_) + alpha3 * y_ * Math.Sin(x_ * y_)) / M4) - p0 / Math.Cos(x_ * y_) / (alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4) * Math.Cos(y_) * Math.Sin(x_) + p0 * Math.Pow(Math.Cos(x_ * y_), -0.2e1) / (alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4) * Math.Pow(Math.Cos(y_), 0.2e1) * x_ * Math.Sin(x_ * y_) - p0 / Math.Cos(x_ * y_) * Math.Pow(alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4, -0.2e1) * Math.Pow(Math.Cos(y_), 0.2e1) * (-alpha1 * x_ * Math.Sin(x_ * y_) / M1 - alpha2 * x_ * Math.Sin(x_ * y_) / M2 - alpha3 * x_ * Math.Sin(x_ * y_) / M3 + (alpha1 * x_ * Math.Sin(x_ * y_) + alpha2 * x_ * Math.Sin(x_ * y_) + alpha3 * x_ * Math.Sin(x_ * y_)) / M4) - 0.2e1 * p0 / Math.Cos(x_ * y_) / (alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4) * Math.Cos(y_) * Math.Sin(y_); BouyancyTerm = Math.Pow(Froude, -0.2e1) * p0 / Math.Cos(x_ * y_) / (alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4); break; default: throw new NotImplementedException("should not happen"); } ViscTerm = -0.4e1 / 0.3e1 * Math.Cos(y_) / Reynolds; // PressureGradientTerm = x_ * Math.Cos(x_ * y_); } else { throw new ArgumentException("Specified direction not supported"); } } return(-(unsteadyTerm + ConvectionTerm + ViscTerm + PressureGradientTerm + BouyancyTerm * -1)); }
//Manufactured solution for T = cos(x*y), Y0 = 0.3 cos(x*y), Y1 = 0.6 cos(x*y), Y2 = 0.1 cos(x*y), u = -cos(x), v = -cos(y), p = sin(x*y). protected override double Source(double[] x, double[] parameters, double[] U) { double x_ = x[0]; double y_ = x[1]; double t_ = 0.0; double p0 = ThermodynamicPressure.GetMeanValue(3); double M1 = MolarMasses[0]; double M2 = MolarMasses[1]; double M3 = MolarMasses[2]; double M4 = MolarMasses[3]; double alpha1 = 0.3; double alpha2 = 0.6; double alpha3 = 0.1; double[] Coefficients = new double[] { alpha1, alpha2, alpha3 }; bool unsteady = false; double ConvectionTerm; double ReactionRate; double SourceTerm; double DiffussionTerm; double unsteadyTerm = 0.0; if (unsteady) { switch (physicsMode) { case PhysicsMode.LowMach: ConvectionTerm = p0 * t_ * Math.Sin(x_ * t_) + p0 * t_ * Math.Sin(y_ * t_); ReactionRate = 0; unsteadyTerm = 0.0; // 0.0 is the correct MS... ((p0/T)*T)' = (p0)' = 0.0 break; case PhysicsMode.Combustion: ConvectionTerm = 0.0; //TODO ReactionRate = 0.0; //TODO break; default: throw new NotImplementedException("wrong switch"); } switch (EqType) { case "Temperature": DiffussionTerm = 1.0 / (ReynoldsNumber * PrandtlNumber) * (y_ * y_ * t_ * t_ * Math.Cos(x_ * y_ * t_) + x_ * x_ * t_ * t_ * Math.Cos(x_ * y_ * t_)); SourceTerm = 0.0; //TODO return(-(unsteadyTerm + ConvectionTerm + DiffussionTerm + SourceTerm)); case "MassFraction": if (SpeciesIndex == -1) { throw new ArgumentException("Species index needs to be specified"); } ConvectionTerm *= Coefficients[SpeciesIndex]; double alpha; switch (SpeciesIndex) { case 0: alpha = alpha1; break; case 1: alpha = alpha2; break; case 2: alpha = alpha3; break; default: throw new NotImplementedException("wrong index"); } switch (physicsMode) { case PhysicsMode.LowMach: DiffussionTerm = 0.0; //TODO break; case PhysicsMode.Combustion: DiffussionTerm = 0.0; //TODO break; default: throw new NotImplementedException("wrong switch"); } SourceTerm = -MolarMasses[SpeciesIndex] * StoichiometricCoeff * ReactionRate; return(-(ConvectionTerm + -DiffussionTerm + SourceTerm)); // TODO CHECK SIGNS default: throw new NotImplementedException(); } } else { switch (physicsMode) { case PhysicsMode.LowMach: ConvectionTerm = p0 * Math.Sin(x_) + p0 * Math.Sin(y_); ReactionRate = 0; break; case PhysicsMode.Combustion: ConvectionTerm = p0 * Math.Pow(alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4, -0.2e1) * Math.Cos(x_) * (-alpha1 * y_ * Math.Sin(x_ * y_) / M1 - alpha2 * y_ * Math.Sin(x_ * y_) / M2 - alpha3 * y_ * Math.Sin(x_ * y_) / M3 + (alpha1 * y_ * Math.Sin(x_ * y_) + alpha2 * y_ * Math.Sin(x_ * y_) + alpha3 * y_ * Math.Sin(x_ * y_)) / M4) + p0 / (alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4) * Math.Sin(x_) + p0 * Math.Pow(alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4, -0.2e1) * Math.Cos(y_) * (-alpha1 * x_ * Math.Sin(x_ * y_) / M1 - alpha2 * x_ * Math.Sin(x_ * y_) / M2 - alpha3 * x_ * Math.Sin(x_ * y_) / M3 + (alpha1 * x_ * Math.Sin(x_ * y_) + alpha2 * x_ * Math.Sin(x_ * y_) + alpha3 * x_ * Math.Sin(x_ * y_)) / M4) + p0 / (alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4) * Math.Sin(y_); ReactionRate = PreExpFactor * OneOverMolarMass0MolarMass1 * Math.Exp(-0.1e1 / Math.Cos(x_ * y_)) * Math.Pow(p0, 0.3e1) * Math.Pow(alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4, -0.3e1) * alpha1 * alpha2 * alpha2; break; default: throw new NotImplementedException("wrong switch"); } switch (EqType) { case "Temperature": DiffussionTerm = 1.0 / (ReynoldsNumber * PrandtlNumber) * Math.Cos(x_ * y_) * (Math.Pow(x_, 2) + Math.Pow(y_, 2)); // OK SourceTerm = HeatReleaseFactor * Math.Cos(x_ * y_) * ReactionRate; return(-(ConvectionTerm + DiffussionTerm + SourceTerm)); case "MassFraction": if (SpeciesIndex == -1) { throw new ArgumentException("Species index needs to be specified"); } ConvectionTerm *= Coefficients[SpeciesIndex]; double alpha; switch (SpeciesIndex) { case 0: alpha = alpha1; break; case 1: alpha = alpha2; break; case 2: alpha = alpha3; break; default: throw new NotImplementedException("wrong index"); } switch (physicsMode) { case PhysicsMode.LowMach: DiffussionTerm = -p0 *Math.Pow(Math.Cos(x_ *y_), -0.2e1) * alpha * y_ * y_ * Math.Pow(Math.Sin(x_ * y_), 0.2e1) - p0 * alpha * y_ * y_ - p0 * Math.Pow(Math.Cos(x_ * y_), -0.2e1) * alpha * x_ * x_ * Math.Pow(Math.Sin(x_ * y_), 0.2e1) - p0 * alpha * x_ * x_; break; case PhysicsMode.Combustion: DiffussionTerm = 1.0 / (ReynoldsNumber * SchmidtNumber) * (-p0 * Math.Pow(Math.Cos(x_ * y_), -0.2e1) / (alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4) * alpha * y_ * y_ * Math.Pow(Math.Sin(x_ * y_), 0.2e1) + p0 / Math.Cos(x_ * y_) * Math.Pow(alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4, -0.2e1) * alpha * y_ * Math.Sin(x_ * y_) * (-alpha1 * y_ * Math.Sin(x_ * y_) / M1 - alpha2 * y_ * Math.Sin(x_ * y_) / M2 - alpha3 * y_ * Math.Sin(x_ * y_) / M3 + (alpha1 * y_ * Math.Sin(x_ * y_) + alpha2 * y_ * Math.Sin(x_ * y_) + alpha3 * y_ * Math.Sin(x_ * y_)) / M4) - p0 / (alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4) * alpha * y_ * y_ - p0 * Math.Pow(Math.Cos(x_ * y_), -0.2e1) / (alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4) * alpha * x_ * x_ * Math.Pow(Math.Sin(x_ * y_), 0.2e1) + p0 / Math.Cos(x_ * y_) * Math.Pow(alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4, -0.2e1) * alpha * x_ * Math.Sin(x_ * y_) * (-alpha1 * x_ * Math.Sin(x_ * y_) / M1 - alpha2 * x_ * Math.Sin(x_ * y_) / M2 - alpha3 * x_ * Math.Sin(x_ * y_) / M3 + (alpha1 * x_ * Math.Sin(x_ * y_) + alpha2 * x_ * Math.Sin(x_ * y_) + alpha3 * x_ * Math.Sin(x_ * y_)) / M4) - p0 / (alpha1 * Math.Cos(x_ * y_) / M1 + alpha2 * Math.Cos(x_ * y_) / M2 + alpha3 * Math.Cos(x_ * y_) / M3 + (0.10e1 - alpha1 * Math.Cos(x_ * y_) - alpha2 * Math.Cos(x_ * y_) - alpha3 * Math.Cos(x_ * y_)) / M4) * alpha * x_ * x_); break; default: throw new NotImplementedException("wrong switch"); } SourceTerm = -MolarMasses[SpeciesIndex] * StoichiometricCoeff * ReactionRate; return(-(ConvectionTerm + -DiffussionTerm + SourceTerm)); // TODO CHECK SIGNS default: throw new NotImplementedException(); } } }