示例#1
0
        /// <summary>
        /// Computes the maximum admissible step-size according to
        /// GassnerEtAl2008, equation 67.
        /// </summary>
        /// <param name="i0"></param>
        /// <param name="Length"></param>
        /// <returns></returns>
        protected override double GetCFLStepSize(int i0, int Length)
        {
            int iKref            = gridData.Cells.GetRefElementIndex(i0);
            int noOfNodesPerCell = base.EvaluationPoints[iKref].NoOfNodes;

            MultidimensionalArray levelSetValues =
                speciesMap.Tracker.DataHistories[0].Current.GetLevSetValues(base.EvaluationPoints[iKref], i0, Length);
            SpeciesId species   = speciesMap.Tracker.GetSpeciesId(speciesMap.Control.FluidSpeciesName);
            var       hMinArray = speciesMap.CellAgglomeration.CellLengthScales[species];
            //var volFrac = speciesMap.QuadSchemeHelper.CellAgglomeration.CellVolumeFrac[species];
            //var hMinGass = speciesMap.h_min;
            //var hMin = gridData.Cells.h_min;

            double cfl = double.MaxValue;

            for (int i = 0; i < Length; i++)
            {
                int cell = i0 + i;

                //double hmin = hMin[cell] * volFrac[cell];
                double hmin = hMinArray[cell];
                //double hmin = hMinGass[cell];

                for (int node = 0; node < noOfNodesPerCell; node++)
                {
                    if (levelSetValues[i, node].Sign() != (double)speciesMap.Control.FluidSpeciesSign)
                    {
                        continue;
                    }

                    Material material = speciesMap.GetMaterial(double.NaN);
                    Vector3D momentum = new Vector3D();
                    for (int d = 0; d < CNSEnvironment.NumberOfDimensions; d++)
                    {
                        momentum[d] = momentumValues[d][i, node];
                    }

                    StateVector state = new StateVector(
                        material, densityValues[i, node], momentum, energyValues[i, node]);

                    double coeff   = Math.Max(4.0 / 3.0, config.EquationOfState.HeatCapacityRatio / config.PrandtlNumber);
                    double cflhere = hmin * hmin / coeff / (state.GetViscosity(cell) / config.ReynoldsNumber);

#if DEBUG
                    if (double.IsNaN(cflhere))
                    {
                        throw new Exception("Could not determine CFL number");
                    }
#endif

                    cfl = Math.Min(cfl, cflhere);
                }
            }

            int degree      = workingSet.ConservativeVariables.Max(f => f.Basis.Degree);
            int twoNPlusOne = 2 * degree + 1;
            return(cfl * GetBetaMax(degree) / twoNPlusOne / twoNPlusOne / Math.Sqrt(CNSEnvironment.NumberOfDimensions));
            //return cfl / twoNPlusOne / twoNPlusOne;
        }
        /// <summary>
        /// Computes the maximum admissible step-size according to
        /// GassnerEtAl2008, equation 67.
        /// </summary>
        /// <param name="i0"></param>
        /// <param name="Length"></param>
        /// <returns></returns>
        protected override double GetCFLStepSize(int i0, int Length)
        {
            int      iKref            = gridData.Cells.GetRefElementIndex(i0);
            int      noOfNodesPerCell = base.EvaluationPoints[iKref].NoOfNodes;
            Material material         = speciesMap.GetMaterial(double.NaN);
            var      hmin             = gridData.Cells.h_min;
            double   scaling          = Math.Max(4.0 / 3.0, config.EquationOfState.HeatCapacityRatio / config.PrandtlNumber);

            // Following code is performance-critical, so expect spagetti code ahead
            double cfl = double.MaxValue;

            switch (speciesMap)
            {
            // 1) IBM optimized (ignores nodes in the void part of a cell, only applies to constant viscosity gases)
            case ImmersedSpeciesMap ibmMap when material.ViscosityLaw is ConstantViscosity: {
                MultidimensionalArray levelSetValues =
                    ibmMap.Tracker.DataHistories[0].Current.GetLevSetValues(base.EvaluationPoints[iKref], i0, Length);

                SpeciesId species = ibmMap.Tracker.GetSpeciesId(ibmMap.Control.FluidSpeciesName);
                //var hMin = speciesMap.QuadSchemeHelper.CellAgglomeration.CellLengthScales[species];
                var volFrac = ibmMap.CellAgglomeration.CellVolumeFrac[species];

                double nu = 1.0 / config.ReynoldsNumber;
                for (int i = 0; i < Length; i++)
                {
                    int cell = i0 + i;

                    double hminlocal = hmin[cell] * volFrac[cell];
                    //double hminlocal = hMin[cell];
                    //double hmin = hMinGass[cell];

                    for (int node = 0; node < noOfNodesPerCell; node++)
                    {
                        if (levelSetValues[i, node].Sign() != (double)ibmMap.Control.FluidSpeciesSign)
                        {
                            continue;
                        }

                        double cflhere = hminlocal * hminlocal / scaling / nu;

#if DEBUG
                        if (double.IsNaN(cflhere))
                        {
                            throw new Exception("Could not determine CFL number");
                        }
#endif

                        cfl = Math.Min(cfl, cflhere);
                    }
                }
            }
            break;

            // 2) IBM generic (ignores nodes in the void part of a cell)
            case ImmersedSpeciesMap ibmMap: {
                MultidimensionalArray levelSetValues =
                    ibmMap.Tracker.DataHistories[0].Current.GetLevSetValues(base.EvaluationPoints[iKref], i0, Length);

                SpeciesId species = ibmMap.Tracker.GetSpeciesId(ibmMap.Control.FluidSpeciesName);
                //var hMin = speciesMap.QuadSchemeHelper.CellAgglomeration.CellLengthScales[species];
                var volFrac = ibmMap.CellAgglomeration.CellVolumeFrac[species];

                for (int i = 0; i < Length; i++)
                {
                    int cell = i0 + i;

                    double hminlocal = hmin[cell] * volFrac[cell];
                    //double hminlocal = hMin[cell];
                    //double hmin = hMinGass[cell];

                    for (int node = 0; node < noOfNodesPerCell; node++)
                    {
                        if (levelSetValues[i, node].Sign() != (double)ibmMap.Control.FluidSpeciesSign)
                        {
                            continue;
                        }

                        Vector3D momentum = new Vector3D();
                        for (int d = 0; d < CNSEnvironment.NumberOfDimensions; d++)
                        {
                            momentum[d] = momentumValues[d][i, node];
                        }

                        StateVector state = new StateVector(
                            material, densityValues[i, node], momentum, energyValues[i, node]);
                        double nu = state.GetViscosity(cell) / config.ReynoldsNumber;
                        Debug.Assert(nu > 0.0);

                        double cflhere = hminlocal * hminlocal / scaling / nu;

#if DEBUG
                        if (double.IsNaN(cflhere))
                        {
                            throw new Exception("Could not determine CFL number");
                        }
#endif

                        cfl = Math.Min(cfl, cflhere);
                    }
                }
            }
            break;

            // 3) Non-IBM optimized (only applies to constant viscosity gases)
            case var speciesMap when material.ViscosityLaw is ConstantViscosity: {
                double nu = 1.0 / config.ReynoldsNumber;         // Constant viscosity
                for (int i = 0; i < Length; i++)
                {
                    int cell = i0 + i;

                    for (int node = 0; node < noOfNodesPerCell; node++)
                    {
                        double hminlocal = gridData.Cells.h_min[cell];
                        double cflhere   = hminlocal * hminlocal / scaling / nu;
                        cfl = Math.Min(cfl, cflhere);
                    }
                }
            }
            break;

            // 4) Non-IBM generic (works for all viscosity laws)
            default: {
                for (int i = 0; i < Length; i++)
                {
                    int cell = i0 + i;

                    for (int node = 0; node < noOfNodesPerCell; node++)
                    {
                        Vector3D momentum = new Vector3D();
                        for (int d = 0; d < CNSEnvironment.NumberOfDimensions; d++)
                        {
                            momentum[d] = momentumValues[d][i, node];
                        }

                        StateVector state = new StateVector(
                            material, densityValues[i, node], momentum, energyValues[i, node]);

                        double hminlocal = hmin[cell];

                        double nu = state.GetViscosity(cell) / config.ReynoldsNumber;
                        Debug.Assert(nu > 0.0);

                        double cflhere = hminlocal * hminlocal / scaling / nu;
                        cfl = Math.Min(cfl, cflhere);
                    }
                }
            }
            break;
            }

            int degree      = workingSet.ConservativeVariables.Max(f => f.Basis.Degree);
            int twoNPlusOne = 2 * degree + 1;
            return(cfl * GetBetaMax(degree) / twoNPlusOne / twoNPlusOne / Math.Sqrt(CNSEnvironment.NumberOfDimensions));
        }
示例#3
0
        /// <summary>
        /// <see cref="SIPGFlux.UpdateTensorComponent(StateVector, bool, double[,,], int)"/>
        /// </summary>
        /// <param name="state"></param>
        /// <param name="adiabaticWall"></param>
        /// <param name="Tensor"></param>
        /// <param name="cellIndex"></param>
        protected override void UpdateTensorComponent(StateVector state, bool adiabaticWall, double[, ,] Tensor, int cellIndex)
        {
            double Viscosity = state.GetViscosity(cellIndex);
            double gamma     = config.EquationOfState.HeatCapacityRatio;
            double gamma_Pr  = adiabaticWall ? 0 :
                               gamma / config.PrandtlNumber;
            double mu_rhoRe     = Viscosity / config.ReynoldsNumber / state.Density;
            double MachsScaling = gamma * config.MachNumber * config.MachNumber;

            double v1 = state.Momentum[0] / state.Density;
            double v2 = state.Momentum[1] / state.Density;
            double v3 = state.Momentum[2] / state.Density;
            double E  = state.Energy / state.Density;
            double VelocitySquared = v1 * v1 + v2 * v2 + v3 * v3;

            switch (dimension)
            {
            case 1:
                Tensor[0, 0, 0] = -(MachsScaling * (alphaPlus13 * v1 * v1 + VelocitySquared) + gamma_Pr * (E - MachsScaling * VelocitySquared)) * mu_rhoRe;
                Tensor[0, 0, 1] = MachsScaling * (alphaPlus43 - gamma_Pr) * v1 * mu_rhoRe;
                Tensor[0, 0, 2] = gamma_Pr * mu_rhoRe;
                break;

            case 2:
                // G_xx
                Tensor[0, 0, 0] = -(MachsScaling * (alphaPlus13 * v1 * v1 + VelocitySquared) + gamma_Pr * (E - MachsScaling * VelocitySquared)) * mu_rhoRe;
                Tensor[0, 0, 1] = MachsScaling * (alphaPlus43 - gamma_Pr) * v1 * mu_rhoRe;
                Tensor[0, 0, 2] = MachsScaling * (1 - gamma_Pr) * v2 * mu_rhoRe;
                Tensor[0, 0, 3] = gamma_Pr * mu_rhoRe;

                // G_xy
                Tensor[0, 1, 0] = -MachsScaling * alphaPlus13 * v1 * v2 * mu_rhoRe;
                Tensor[0, 1, 1] = MachsScaling * v2 * mu_rhoRe;
                Tensor[0, 1, 2] = MachsScaling * alphaMinus23 * v1 * mu_rhoRe;
                //Tensor[0, 1, 3] = 0*eta_rhoRe;

                // G_yx
                Tensor[1, 0, 0] = -MachsScaling * (alphaPlus43 - 1.0) * v1 * v2 * mu_rhoRe;
                Tensor[1, 0, 1] = MachsScaling * alphaMinus23 * v2 * mu_rhoRe;
                Tensor[1, 0, 2] = MachsScaling * v1 * mu_rhoRe;
                //Tensor[1, 0, 3] = 0*eta_rhoRe;

                // G_yy
                Tensor[1, 1, 0] = -(MachsScaling * (alphaPlus13 * v2 * v2 + VelocitySquared) + gamma_Pr * (E - MachsScaling * VelocitySquared)) * mu_rhoRe;
                Tensor[1, 1, 1] = MachsScaling * (1 - gamma_Pr) * v1 * mu_rhoRe;
                Tensor[1, 1, 2] = MachsScaling * (alphaPlus43 - gamma_Pr) * v2 * mu_rhoRe;
                Tensor[1, 1, 3] = gamma_Pr * mu_rhoRe;
                break;

            case 3:
                // G_xx
                Tensor[0, 0, 0] = -(MachsScaling * (alphaPlus13 * v1 * v1 + VelocitySquared) + gamma_Pr * (E - MachsScaling * VelocitySquared)) * mu_rhoRe;
                Tensor[0, 0, 1] = MachsScaling * (alphaPlus43 - gamma_Pr) * v1 * mu_rhoRe;
                Tensor[0, 0, 2] = MachsScaling * (1 - gamma_Pr) * v2 * mu_rhoRe;
                Tensor[0, 0, 3] = MachsScaling * (1 - gamma_Pr) * v3 * mu_rhoRe;
                Tensor[0, 0, 4] = gamma_Pr * mu_rhoRe;

                // G_xy
                Tensor[0, 1, 0] = -MachsScaling * alphaPlus13 * v1 * v2 * mu_rhoRe;
                Tensor[0, 1, 1] = MachsScaling * v2 * mu_rhoRe;
                Tensor[0, 1, 2] = MachsScaling * alphaMinus23 * v1 * mu_rhoRe;
                //Tensor[0, 1, 3] = 0 * eta_rhoRe;
                //Tensor[0, 1, 4] = 0 * eta_rhoRe;

                // G_xz
                Tensor[0, 2, 0] = -MachsScaling * alphaPlus13 * v1 * v3 * mu_rhoRe;
                Tensor[0, 2, 1] = MachsScaling * v3 * mu_rhoRe;
                //Tensor[0, 2, 2] = 0 * eta_rhoRe;
                Tensor[0, 2, 3] = MachsScaling * alphaMinus23 * v1 * mu_rhoRe;
                //Tensor[0, 2, 4] = 0 * eta_rhoRe;


                // G_yx
                Tensor[1, 0, 0] = -MachsScaling * alphaPlus13 * v1 * v2 * mu_rhoRe;
                Tensor[1, 0, 1] = MachsScaling * alphaMinus23 * v2 * mu_rhoRe;
                Tensor[1, 0, 2] = MachsScaling * v1 * mu_rhoRe;
                //Tensor[1, 0, 3] = 0 * eta_rhoRe;
                //Tensor[1, 0, 4] = 0 * eta_rhoRe;


                // G_yy
                Tensor[1, 1, 0] = -(MachsScaling * (alphaPlus13 * v2 * v2 + VelocitySquared) + gamma_Pr * (E - MachsScaling * VelocitySquared)) * mu_rhoRe;
                Tensor[1, 1, 1] = MachsScaling * (1 - gamma_Pr) * v1 * mu_rhoRe;
                Tensor[1, 1, 2] = MachsScaling * (alphaPlus43 - gamma_Pr) * v2 * mu_rhoRe;
                Tensor[1, 1, 3] = MachsScaling * (1 - gamma_Pr) * v3 * mu_rhoRe;
                Tensor[1, 1, 4] = gamma_Pr * mu_rhoRe;

                // G_yz
                Tensor[1, 2, 0] = -MachsScaling * alphaPlus13 * v2 * v3 * mu_rhoRe;
                //Tensor[1, 2, 1] = 0 * eta_rhoRe;
                Tensor[1, 2, 2] = MachsScaling * v3 * mu_rhoRe;
                Tensor[1, 2, 3] = MachsScaling * alphaMinus23 * v2 * mu_rhoRe;
                //Tensor[1, 2, 4] = 0 * eta_rhoRe;

                // G_zx
                Tensor[2, 0, 0] = -MachsScaling * alphaPlus13 * v1 * v3 * mu_rhoRe;
                Tensor[2, 0, 1] = MachsScaling * alphaMinus23 * v3 * mu_rhoRe;
                //Tensor[2, 0, 2] = 0 * eta_rhoRe;
                Tensor[2, 0, 3] = MachsScaling * v1 * mu_rhoRe;
                //Tensor[2, 0, 4] = 0 * eta_rhoRe;

                // G_zy
                Tensor[2, 1, 0] = -MachsScaling * alphaPlus13 * v2 * v3 * mu_rhoRe;
                //Tensor[2, 1, 1] = 0 * eta_rhoRe;
                Tensor[2, 1, 2] = MachsScaling * alphaMinus23 * v3 * mu_rhoRe;
                Tensor[2, 1, 3] = MachsScaling * v2 * mu_rhoRe;
                //Tensor[2, 1, 4] = 0 * eta_rhoRe;

                // G_zz
                Tensor[2, 2, 0] = -(MachsScaling * (alphaPlus13 * v3 * v3 + VelocitySquared) + gamma_Pr * (E - MachsScaling * VelocitySquared)) * mu_rhoRe;
                Tensor[2, 2, 1] = MachsScaling * (1 - gamma_Pr) * v1 * mu_rhoRe;
                Tensor[2, 2, 2] = MachsScaling * (1 - gamma_Pr) * v2 * mu_rhoRe;
                Tensor[2, 2, 3] = MachsScaling * (alphaPlus43 - gamma_Pr) * v3 * mu_rhoRe;
                Tensor[2, 2, 4] = gamma_Pr * mu_rhoRe;

                break;
            }
        }
示例#4
0
        /// <summary>
        /// <see cref="SIPGFlux.UpdateTensorComponent(StateVector, bool, double[,,], int)"/>
        /// </summary>
        /// <param name="state"></param>
        /// <param name="adiabaticWall"></param>
        /// <param name="Tensor"></param>
        /// <param name="cellIndex"></param>
        protected override void UpdateTensorComponent(StateVector state, bool adiabaticWall, double[, ,] Tensor, int cellIndex)
        {
            //TO-DO: temperature dependent thermal conductivity/viscosity
            // double ThermalConductivity = state.ThermalConductivity

            double Viscosity           = state.GetViscosity(cellIndex);
            double ThermalConductivity = Viscosity;
            double mu_rhoRe            = Viscosity / config.ReynoldsNumber / state.Density;

            double v1 = state.Velocity[0];
            double v2 = state.Velocity[1];
            double v3 = state.Velocity[2];

            switch (dimension)
            {
            case 1:
                Tensor[0, 0, 0] = -(alphaPlus43) * v1 * mu_rhoRe;
                Tensor[0, 0, 1] = alphaPlus43 * mu_rhoRe;
                //Tensor[0, 0, 2] = 0 * eta_rhoRe;
                break;

            case 2:
                switch (component)
                {
                case 1:         // x-momentum
                    //G_xx
                    Tensor[0, 0, 0] = -(alphaPlus43) * v1 * mu_rhoRe;
                    Tensor[0, 0, 1] = alphaPlus43 * mu_rhoRe;
                    //Tensor[0, 0, 2] = 0 * eta_rhoRe;
                    //Tensor[0, 0, 3] = 0 * eta_rhoRe;

                    //G_xy
                    Tensor[0, 1, 0] = -alphaMinus23 * v2 * mu_rhoRe;
                    //Tensor[0, 1, 1] = 0 * eta_rhoRe;
                    Tensor[0, 1, 2] = alphaMinus23 * mu_rhoRe;
                    //Tensor[0, 1, 3] = 0 * eta_rhoRe;

                    // G_yx
                    Tensor[1, 0, 0] = -v2 * mu_rhoRe;
                    //Tensor[1, 0, 1] = 0 * eta_rhoRe;
                    Tensor[1, 0, 2] = 1 * mu_rhoRe;
                    //Tensor[1, 0, 3] = 0 * eta_rhoRe;

                    //G_yy
                    Tensor[1, 1, 0] = -v1 * mu_rhoRe;
                    Tensor[1, 1, 1] = 1 * mu_rhoRe;
                    //Tensor[1, 1, 2] = 0 * eta_rhoRe;
                    //Tensor[1, 1, 3] = 0 * eta_rhoRe;

                    break;

                case 2:         // y-momentum
                    //G_xx
                    Tensor[0, 0, 0] = -v2 * mu_rhoRe;
                    //Tensor[0, 0, 1] = 0 * eta_rhoRe;
                    Tensor[0, 0, 2] = 1 * mu_rhoRe;
                    //Tensor[0, 0, 3] = 0 * eta_rhoRe;

                    //G_xy
                    Tensor[0, 1, 0] = -v2 * mu_rhoRe;
                    Tensor[0, 1, 1] = 1 * mu_rhoRe;
                    //Tensor[0, 1, 2] = 0 * eta_rhoRe;
                    //Tensor[0, 1, 3] = 0 * eta_rhoRe;

                    // G_yx
                    Tensor[1, 0, 0] = -alphaMinus23 * v1 * mu_rhoRe;
                    Tensor[1, 0, 1] = alphaMinus23 * mu_rhoRe;
                    //Tensor[1, 0, 2] = 0 * eta_rhoRe;
                    //Tensor[1, 0, 3] = 0 * eta_rhoRe;

                    //G_yy
                    Tensor[1, 1, 0] = -(alphaPlus43) * v2 * mu_rhoRe;
                    //Tensor[1, 1, 1] = 0 * eta_rhoRe;
                    Tensor[1, 1, 2] = alphaPlus43 * mu_rhoRe;
                    //Tensor[1, 1, 3] = 0 * eta_rhoRe;
                    break;
                }
                break;

            case 3:
                switch (component)
                {
                case 1:         // x-momentum
                    //G_xx
                    Tensor[0, 0, 0] = -alphaPlus43 * v1 * mu_rhoRe;
                    Tensor[0, 0, 1] = alphaPlus43 * mu_rhoRe;
                    //Tensor[0, 0, 2] = 0 * eta_rhoRe;
                    //Tensor[0, 0, 3] = 0 * eta_rhoRe;
                    //Tensor[0, 0, 4] = 0 * eta_rhoRe;

                    //G_xy
                    Tensor[0, 1, 0] = -alphaMinus23 * v2 * mu_rhoRe;
                    //Tensor[0, 1, 1] = 0 * eta_rhoRe;
                    Tensor[0, 1, 2] = alphaMinus23 * mu_rhoRe;
                    //Tensor[0, 1, 3] = 0 * eta_rhoRe;
                    //Tensor[0, 1, 4] = 0 * eta_rhoRe;

                    //G_xz
                    Tensor[0, 2, 0] = -alphaMinus23 * v3 * mu_rhoRe;
                    //Tensor[0, 2, 1] = 0 * eta_rhoRe;
                    //Tensor[0, 2, 2] = 0 * eta_rhoRe;
                    Tensor[0, 2, 3] = alphaMinus23 * mu_rhoRe;
                    //Tensor[0, 2, 4] = 0 * eta_rhoRe;


                    // G_yx
                    Tensor[1, 0, 0] = -v2 * mu_rhoRe;
                    //Tensor[1, 0, 1] = 0 * eta_rhoRe;
                    Tensor[1, 0, 2] = 1 * mu_rhoRe;
                    //Tensor[1, 0, 3] = 0 * eta_rhoRe;
                    //Tensor[1, 0, 4] = 0 * eta_rhoRe;

                    //G_yy
                    Tensor[1, 1, 0] = -v1 * mu_rhoRe;
                    Tensor[1, 1, 1] = 1 * mu_rhoRe;
                    //Tensor[1, 1, 2] = 0 * eta_rhoRe;
                    //Tensor[1, 1, 3] = 0 * eta_rhoRe;
                    //Tensor[1, 1, 4] = 0 * eta_rhoRe;

                    //G_yz
                    //Tensor[1, 2, 0] = 0 * eta_rhoRe;
                    //Tensor[1, 2, 1] = 0 * eta_rhoRe;
                    //Tensor[1, 2, 2] = 0 * eta_rhoRe;
                    //Tensor[1, 2, 3] = 0 * eta_rhoRe;
                    //Tensor[1, 2, 4] = 0 * eta_rhoRe;

                    // G_zx
                    Tensor[2, 0, 0] = -v3 * mu_rhoRe;
                    //Tensor[2, 0, 1] = 0 * eta_rhoRe;
                    //Tensor[2, 0, 2] = 0 * eta_rhoRe;
                    Tensor[2, 0, 3] = 1 * mu_rhoRe;
                    //Tensor[2, 0, 4] = 0 * eta_rhoRe;

                    //G_zy
                    //Tensor[2, 1, 0] = 0 * eta_rhoRe;
                    //Tensor[2, 1, 1] = 0 * eta_rhoRe;
                    //Tensor[2, 1, 2] = 0 * eta_rhoRe;
                    //Tensor[2, 1, 3] = 0 * eta_rhoRe;
                    //Tensor[2, 1, 4] = 0 * eta_rhoRe;

                    //G_zz
                    Tensor[2, 2, 0] = -v1 * mu_rhoRe;
                    Tensor[2, 2, 1] = 1 * mu_rhoRe;
                    //Tensor[2, 2, 2] = 0 * eta_rhoRe;
                    //Tensor[2, 2, 3] = 0 * eta_rhoRe;
                    //Tensor[2, 2, 4] = 0 * eta_rhoRe;

                    break;

                case 2:         // y-momentum
                    //G_xx
                    Tensor[0, 0, 0] = -v2 * mu_rhoRe;
                    //Tensor[0, 0, 1] = 0 * eta_rhoRe;
                    Tensor[0, 0, 2] = 1 * mu_rhoRe;
                    //Tensor[0, 0, 3] = 0 * eta_rhoRe;
                    //Tensor[0, 0, 4] = 0 * eta_rhoRe;

                    //G_xy
                    Tensor[0, 1, 0] = -v1 * mu_rhoRe;
                    Tensor[0, 1, 1] = 1 * mu_rhoRe;
                    //Tensor[0, 1, 2] = 0 * eta_rhoRe;
                    //Tensor[0, 1, 3] = 0 * eta_rhoRe;
                    //Tensor[0, 1, 4] = 0 * eta_rhoRe;

                    //G_xz
                    //Tensor[0, 2, 0] = 0 * eta_rhoRe;
                    //Tensor[0, 2, 1] = 0 * eta_rhoRe;
                    //Tensor[0, 2, 2] = 0 * eta_rhoRe;
                    //Tensor[0, 2, 3] = 0 * eta_rhoRe;
                    //Tensor[0, 2, 4] = 0 * eta_rhoRe;

                    // G_yx
                    Tensor[1, 0, 0] = -alphaMinus23 * v1 * mu_rhoRe;
                    Tensor[1, 0, 1] = alphaMinus23 * mu_rhoRe;
                    //Tensor[1, 0, 2] = 0 * eta_rhoRe;
                    //Tensor[1, 0, 3] = 0 * eta_rhoRe;
                    //Tensor[1, 0, 4] = 0 * eta_rhoRe;

                    //G_yy
                    Tensor[1, 1, 0] = -alphaPlus43 * v2 * mu_rhoRe;
                    //Tensor[1, 1, 1] = 0 * eta_rhoRe;
                    Tensor[1, 1, 2] = alphaPlus43 * mu_rhoRe;
                    //Tensor[1, 1, 3] = 0 * eta_rhoRe;
                    //Tensor[1, 1, 4] = 0 * eta_rhoRe;

                    // G_yz
                    Tensor[1, 2, 0] = -alphaMinus23 * v3 * mu_rhoRe;
                    //Tensor[1, 2, 1] = 0 * eta_rhoRe;
                    //Tensor[1, 2, 2] = 0 * eta_rhoRe;
                    Tensor[1, 2, 3] = alphaMinus23 * mu_rhoRe;
                    //Tensor[1, 2, 4] = 0 * eta_rhoRe;

                    //G_zx
                    //Tensor[2, 0, 0] = 0 * eta_rhoRe;
                    //Tensor[2, 0, 1] = 0 * eta_rhoRe;
                    //Tensor[2, 0, 2] = 0 * eta_rhoRe;
                    //Tensor[2, 0, 3] = 0 * eta_rhoRe;
                    //Tensor[2, 0, 4] = 0 * eta_rhoRe;

                    //G_zy
                    Tensor[2, 1, 0] = -v3 * mu_rhoRe;
                    //Tensor[2, 1, 1] = 0 * eta_rhoRe;
                    //Tensor[2, 1, 2] = 0 * eta_rhoRe;
                    Tensor[2, 1, 3] = 1 * mu_rhoRe;
                    //Tensor[2, 1, 4] = 0 * eta_rhoRe;

                    //G_zz
                    Tensor[2, 2, 0] = -v2 * mu_rhoRe;
                    //Tensor[2, 2, 1] = 0 * eta_rhoRe;
                    Tensor[2, 2, 2] = 1 * mu_rhoRe;
                    //Tensor[2, 2, 3] = 0 * eta_rhoRe;
                    //Tensor[2, 2, 4] = 0 * eta_rhoRe;
                    break;

                case 3:         // z-momentum
                    //G_xx
                    Tensor[0, 0, 0] = -v3 * mu_rhoRe;
                    //Tensor[0, 0, 1] = 0 * eta_rhoRe;
                    //Tensor[0, 0, 2] = 0 * eta_rhoRe;
                    Tensor[0, 0, 3] = 1 * mu_rhoRe;
                    //Tensor[0, 0, 4] = 0 * eta_rhoRe;

                    //G_xy
                    //Tensor[0, 1, 0] = 0 * eta_rhoRe;
                    //Tensor[0, 1, 1] = 0 * eta_rhoRe;
                    //Tensor[0, 1, 2] = 0 * eta_rhoRe;
                    //Tensor[0, 1, 3] = 0 * eta_rhoRe;
                    //Tensor[0, 1, 4] = 0 * eta_rhoRe;

                    //G_xz
                    Tensor[0, 2, 0] = -v1 * mu_rhoRe;
                    Tensor[0, 2, 1] = 1 * mu_rhoRe;
                    //Tensor[0, 2, 2] = 0 * eta_rhoRe;
                    //Tensor[0, 2, 3] = 0 * eta_rhoRe;
                    //Tensor[0, 2, 4] = 0 * eta_rhoRe;

                    // G_yx
                    //Tensor[1, 0, 0] = 0 * eta_rhoRe;
                    //Tensor[1, 0, 1] = 0 * eta_rhoRe;
                    //Tensor[1, 0, 2] = 0 * eta_rhoRe;
                    //Tensor[1, 0, 3] = 0 * eta_rhoRe;
                    //Tensor[1, 0, 4] = 0 * eta_rhoRe;

                    //G_yy
                    Tensor[1, 1, 0] = -v3 * mu_rhoRe;
                    //Tensor[1, 1, 1] = 0 * eta_rhoRe;
                    //Tensor[1, 1, 2] = 0 * eta_rhoRe;
                    Tensor[1, 1, 3] = 1 * mu_rhoRe;
                    //Tensor[1, 1, 4] = 0 * eta_rhoRe;

                    // G_yz
                    Tensor[1, 2, 0] = -v2 * mu_rhoRe;
                    //Tensor[1, 2, 1] = 0 * eta_rhoRe;
                    Tensor[1, 2, 2] = 1 * mu_rhoRe;
                    //Tensor[1, 2, 3] = 0 * eta_rhoRe;
                    //Tensor[1, 2, 4] = 0 * eta_rhoRe;

                    //G_zx
                    Tensor[2, 0, 0] = -alphaMinus23 * v1 * mu_rhoRe;
                    Tensor[2, 0, 1] = alphaMinus23 * mu_rhoRe;
                    //Tensor[2, 0, 2] = 0 * eta_rhoRe;
                    //Tensor[2, 0, 3] = 0 * eta_rhoRe;
                    //Tensor[2, 0, 4] = 0 * eta_rhoRe;

                    //G_zy
                    Tensor[2, 1, 0] = -alphaMinus23 * v2 * mu_rhoRe;
                    //Tensor[2, 1, 1] = 0 * eta_rhoRe;
                    Tensor[2, 1, 2] = alphaMinus23 * mu_rhoRe;
                    //Tensor[2, 1, 3] = 0 * eta_rhoRe;
                    //Tensor[2, 1, 4] = 0 * eta_rhoRe;

                    //G_zz
                    Tensor[2, 2, 0] = -alphaPlus43 * v3 * mu_rhoRe;
                    //Tensor[2, 2, 1] = 0 * eta_rhoRe;
                    //Tensor[2, 2, 2] = 0 * eta_rhoRe;
                    Tensor[2, 2, 3] = alphaPlus43 * mu_rhoRe;
                    //Tensor[2, 2, 4] = 0 * eta_rhoRe;

                    break;
                }
                break;

            default:
                throw new ArgumentOutOfRangeException("dimension");
            }
        }
示例#5
0
        /// <summary>
        /// Defines the force which is integrated over an immersed boundary,
        /// called by <see cref="IBMQueries.LiftOrDragForce"/>
        /// </summary>
        /// <param name="density"></param>
        /// <param name="momentum"></param>
        /// <param name="energy"></param>
        /// <param name="speciesMap"></param>
        /// <param name="direction">Direction of the force projection, e.g. 0=x-axis, 1=y-axis</param>
        /// <param name="cutCellMask">Cells intersected by the interface</param>
        /// <returns></returns>
        static ScalarFunctionEx GetSurfaceForce(
            DGField density, VectorField <DGField> momentum, DGField energy, ImmersedSpeciesMap speciesMap, int direction, CellMask cutCellMask)
        {
            return(delegate(int j0, int Len, NodeSet nodes, MultidimensionalArray result) {
                int noOfNodes = nodes.GetLength(0);
                int D = nodes.SpatialDimension;

                double Reynolds = speciesMap.Control.ReynoldsNumber;
                double Mach = speciesMap.Control.MachNumber;
                double gamma = speciesMap.Control.EquationOfState.HeatCapacityRatio;

                double MachScaling = gamma * Mach * Mach;


                MultidimensionalArray rho = MultidimensionalArray.Create(Len, noOfNodes);
                density.Evaluate(j0, Len, nodes, rho);

                MultidimensionalArray[] m = new MultidimensionalArray[CNSEnvironment.NumberOfDimensions];
                for (int d = 0; d < CNSEnvironment.NumberOfDimensions; d++)
                {
                    m[d] = MultidimensionalArray.Create(Len, noOfNodes);
                    momentum[d].Evaluate(j0, Len, nodes, m[d]);
                }

                MultidimensionalArray rhoE = MultidimensionalArray.Create(Len, noOfNodes);
                energy.Evaluate(j0, Len, nodes, rhoE);

                MultidimensionalArray gradRho = MultidimensionalArray.Create(Len, noOfNodes, D);
                density.EvaluateGradient(j0, Len, nodes, gradRho);

                MultidimensionalArray gradM = MultidimensionalArray.Create(Len, noOfNodes, D, D);
                for (int d = 0; d < D; d++)
                {
                    momentum[d].EvaluateGradient(
                        j0,
                        Len,
                        nodes,
                        gradM.ExtractSubArrayShallow(-1, -1, d, -1),
                        0,
                        0.0);
                }

                MultidimensionalArray normals = speciesMap.Tracker.DataHistories[0].Current.GetLevelSetNormals(nodes, j0, Len);

                Vector3D mVec = new Vector3D();
                for (int i = 0; i < Len; i++)
                {
                    for (int j = 0; j < noOfNodes; j++)
                    {
                        for (int d = 0; d < CNSEnvironment.NumberOfDimensions; d++)
                        {
                            mVec[d] = m[d][i, j];
                        }

                        Material material = speciesMap.GetMaterial(double.NaN);
                        StateVector state = new StateVector(material, rho[i, j], mVec, rhoE[i, j]);

                        double mu = 0.0;
                        if (Reynolds != 0.0)
                        {
                            mu = state.GetViscosity(j0 + j) / Reynolds;
                        }

                        double[,] gradU = new double[D, D];
                        for (int d1 = 0; d1 < D; d1++)
                        {
                            for (int d2 = 0; d2 < D; d2++)
                            {
                                // Apply chain rule
                                gradU[d1, d2] = (gradM[i, j, d1, d2] - state.Momentum[d1] / state.Density * gradRho[i, j, d2]) / state.Density;
                            }
                        }
                        double divU = gradU[0, 0] + gradU[1, 1];

                        switch (direction)
                        {
                        // Attention: Changed sign, because normal vector is pointing inwards, not outwards!
                        case 0:                                                                                // x-Direction
                            result[i, j, 0] = -state.Pressure / MachScaling * normals[i, j, 0]
                                              + mu * (2.0 * gradU[0, 0] - 2.0 / 3.0 * divU) * normals[i, j, 0] //tau_11 * n_1
                                              + mu * (gradU[0, 1] + gradU[1, 0]) * normals[i, j, 1];           //tau_12 * n_2
                            break;

                        case 1:                                                                                 // y-Direction
                            result[i, j, 0] = -state.Pressure / MachScaling * normals[i, j, 1]
                                              + mu * (gradU[0, 1] + gradU[1, 0]) * normals[i, j, 0]             //tau_12 * n_1
                                              + mu * (2.0 * gradU[1, 1] - 2.0 / 3.0 * divU) * normals[i, j, 1]; //tau_22*n_2
                            break;

                        default:
                            throw new ArgumentException("Lift and Drag currently only in 2D implemented");
                        }
                    }
                }
            });
        }