//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);
        }
Exemplo n.º 2
0
        /// <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());
        }
Exemplo n.º 3
0
        /// <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);
        }
Exemplo n.º 4
0
        //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);
        }
Exemplo n.º 5
0
        //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);
        }
Exemplo n.º 6
0
        /// <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);
        }
Exemplo n.º 7
0
        /// <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);
        }
Exemplo n.º 8
0
        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);
            }
        }
Exemplo n.º 9
0
        /// <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);
        }
Exemplo n.º 10
0
        /// <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();
            }
        }
Exemplo n.º 11
0
        /// <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();
            }
        }
Exemplo n.º 12
0
        //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));
        }
Exemplo n.º 13
0
        //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();
                }
            }
        }