Пример #1
0
        /// <summary>
        /// default-implementation
        /// </summary>
        public double LevelSetForm(ref CommonParamsLs inp,
                                   double[] TA, double[] TB, double[,] Grad_uA, double[,] Grad_uB,
                                   double VA, double VB, double[] Grad_vA, double[] Grad_vB)
        {
            double[] N        = inp.n;
            double   hCellMin = this.m_LsTrk.GridDat.Cells.h_min[inp.jCell];

            int D = N.Length;
            //Debug.Assert(this.ArgumentOrdering.Count == 3);

            double PosCellLengthScale = PosLengthScaleS[inp.jCell];
            double NegCellLengthScale = NegLengthScaleS[inp.jCell];

            double hCutCellMin = Math.Min(NegCellLengthScale, PosCellLengthScale);

            if (hCutCellMin <= 1.0e-10 * hCellMin)
            {
                // very small cell -- clippling
                hCutCellMin = hCellMin;
            }

            Debug.Assert(TA.Length == this.ArgumentOrdering.Count);
            Debug.Assert(TB.Length == this.ArgumentOrdering.Count);

            double res = 0;

            res += (TA[0] - TB[0]);

            return(res * 0.5 * (VA + VB));
        }
Пример #2
0
        public double LevelSetForm(ref CommonParamsLs cp, double[] U_Neg, double[] U_Pos, double[,] Grad_uA, double[,] Grad_uB, double v_Neg, double v_Pos, double[] Grad_vA, double[] Grad_vB)
        {
            double uAxN = GenericBlas.InnerProd(U_Neg, cp.n);

            var parameters_P = m_getParticleParams(cp.x, cp.time);

            double[] uLevSet = new double[] { parameters_P[0], parameters_P[1] };
            double   wLevSet = parameters_P[2];

            pRadius = parameters_P[3];
            double scale = parameters_P[4];

            // double scale = parameters_P[4];

            double[] _uLevSet = new double[D];

            _uLevSet[0] = uLevSet[0] + pRadius * wLevSet * -cp.n[1];
            _uLevSet[1] = uLevSet[1] + pRadius * wLevSet * cp.n[0];

            double uBxN = GenericBlas.InnerProd(_uLevSet, cp.n);

            // transform from species B to A: we call this the "A-fictitious" value
            double uAxN_fict;

            uAxN_fict = uBxN;

            double FlxNeg = -DirichletFlux(uAxN, uAxN_fict); // flux on A-side

            //double FlxPos = 0;

            return(FlxNeg * v_Neg);
        }
Пример #3
0
        public virtual double LevelSetForm(ref CommonParamsLs inp,
                                           double[] uA, double[] uB, double[,] Grad_uA, double[,] Grad_uB,
                                           double vA, double vB, double[] Grad_vA, double[] Grad_vB)
        {
            double[] N = inp.n;
            double   Grad_uA_xN = 0, Grad_uB_xN = 0, Grad_vA_xN = 0, Grad_vB_xN = 0;
            int      D = N.Length;

            Debug.Assert(Grad_uA.GetLength(0) == this.ArgumentOrdering.Count);
            Debug.Assert(Grad_uB.GetLength(0) == this.ArgumentOrdering.Count);
            Debug.Assert(Grad_uA.GetLength(1) == D);
            Debug.Assert(Grad_uB.GetLength(1) == D);

            for (int d = 0; d < D; d++)
            {
                Grad_uA_xN += Grad_uA[0, d] * N[d];
                Grad_uB_xN += Grad_uB[0, d] * N[d];
                Grad_vA_xN += Grad_vA[d] * N[d];
                Grad_vB_xN += Grad_vB[d] * N[d];
            }

            double omega_A, omega_B;

            ComputeScaling(ref inp, out omega_A, out omega_B);

            double Ret = 0.0;

            Ret += (muA * omega_A * Grad_uA_xN + muB * omega_B * Grad_uB_xN) * (vA - vB);
            Ret += (muA * omega_A * Grad_vA_xN + muB * omega_B * Grad_vB_xN) * (uA[0] - uB[0]);

            //
            Ret -= GetPenalty(ref inp) * (uA[0] - uB[0]) * (vA - vB);

            return(Ret);
        }
Пример #4
0
        public override double LevelSetForm(ref CommonParamsLs cp, double[] uA, double[] uB, double[,] Grad_uA, double[,] Grad_uB, double vA, double vB, double[] Grad_vA, double[] Grad_vB)
        {
            double[] Normal = cp.n;

            double M = ComputeEvaporationMass(cp.ParamsNeg, cp.ParamsPos, cp.n, cp.jCell);

            if (M == 0.0)
            {
                return(0.0);
            }

            double massFlux = M.Pow2() * ((1 / rhoA) - (1 / rhoB)) * Normal[m_d];

            double p_disp = cp.ParamsNeg[1];
            // augmented capillary pressure
            //double acp_jump = 0.0;
            //if(!double.IsNaN(p_disp))
            //    acp_jump = massFlux + p_disp;
            //else
            //    acp_jump = massFlux;


            double FlxNeg = -0.5 * massFlux;
            double FlxPos = +0.5 * massFlux;


            Debug.Assert(!(double.IsNaN(FlxNeg) || double.IsInfinity(FlxNeg)));
            Debug.Assert(!(double.IsNaN(FlxPos) || double.IsInfinity(FlxPos)));

            double Ret = FlxNeg * vA - FlxPos * vB;

            return(Ret);
        }
Пример #5
0
        //List<int> cellElo = new List<int>();


        protected void ComputeScaling(ref CommonParamsLs inp, out double scaleIN, out double scaleOT)
        {
            Debug.Assert(Math.Sign(muA) == Math.Sign(muB));

            switch (this.m_mode)
            {
            case Mode.SWIP: {
                scaleIN = muB / (muA + muB);
                scaleOT = muA / (muA + muB);
                return;
            }

            case Mode.SIP: {
                // Konventionell:
                scaleIN = 0.5;
                scaleOT = 0.5;
                return;
            }

            /*
             * case Mode.VolumeScaled: {
             * double volIN = this.m_LsTrk._Regions.GetSpeciesVolume(inp.jCell, this.NegativeSpecies);
             * double volOT = this.m_LsTrk._Regions.GetSpeciesVolume(inp.jCell, this.PositiveSpecies);
             *
             * scaleIN = volIN / (volIN + volOT);
             * scaleOT = volOT / (volIN + volOT);
             * Debug.Assert(Math.Abs(scaleIN + scaleOT - 1.0) <= 1.0e-8);
             * return;
             * }
             */

            default:
                throw new NotImplementedException();
            }
        }
Пример #6
0
        /// <summary>
        /// Penalty Term enforcing the Dirichlet value at the interface
        /// Note: this Form is written only in terms of uA, since there is no XDG-field involved
        /// </summary>
        /// <param name="inp">inp.ParamsNeg[0] is the Dirichlet value from the parameter-field</param>
        /// <param name="uA">the unknown</param>
        /// <param name="uB">not needed</param>
        /// <param name="Grad_uA">not needed</param>
        /// <param name="Grad_uB">not needed</param>
        /// <param name="vA">test function</param>
        /// <param name="vB">not needed</param>
        /// <param name="Grad_vA">not needed</param>
        /// <param name="Grad_vB">not needed</param>
        /// <returns>the evaluated penalty flux</returns>
        public double LevelSetForm(ref CommonParamsLs inp, double[] uA, double[] uB, double[,] Grad_uA, double[,] Grad_uB, double vA, double vB, double[] Grad_vA, double[] Grad_vB)
        {
            double NegCellLengthScale = NegCellLengthScaleS[inp.jCell];
            double PosCellLengthScale = (PosCellLengthScaleS != null) ? PosCellLengthScaleS[inp.jCell] : NegCellLengthScaleS[inp.jCell];


            double hmin;

            if (NegCellLengthScale.IsNaN())
            {
                hmin = PosCellLengthScale;
            }
            else if (PosCellLengthScale.IsNaN())
            {
                hmin = NegCellLengthScale;
            }
            else
            {
                hmin = Math.Min(NegCellLengthScale, PosCellLengthScale);
            }

            //return PenaltyBase * 2 / hmin * (uA[0] + uB[0] - inp.ParamsNeg[0] - inp.ParamsPos[0]) * (vA+vB) /4 ;
            return(PenaltyBase * 2 / hmin * (uA[0] - inp.ParamsNeg[0]) * (vA));
            //return PenaltyBase * 2 / hmin * (uB[0] - inp.ParamsPos[0]) * (vB);
        }
Пример #7
0
        public double LevelSetForm(ref CommonParamsLs inp, double[] uA, double[] uB, double[,] Grad_uA, double[,] Grad_uB, double vA, double vB, double[] Grad_vA, double[] Grad_vB)
        {
            double S0 = 0; // velocity in normal direction, at the interface

            for (int d = 0; d < D; d++)
            {
                S0 += inp.n[d] * inp.ParamsNeg[d];
            }

            double hmin;

            if (inp.NegCellLengthScale.IsNaN())
            {
                hmin = inp.PosCellLengthScale;
            }
            else if (inp.PosCellLengthScale.IsNaN())
            {
                hmin = inp.NegCellLengthScale;
            }
            else
            {
                hmin = Math.Min(inp.NegCellLengthScale, inp.PosCellLengthScale);
            }

            double penalty = PenaltyBase / hmin;

            return(penalty * (uA[0] - S0) * vA);
        }
Пример #8
0
        /// <summary>
        /// default-implementation
        /// </summary>
        public double LevelSetForm(ref CommonParamsLs inp,
                                   double[] TA, double[] TB, double[,] Grad_uA, double[,] Grad_uB,
                                   double vA, double vB, double[] Grad_vA, double[] Grad_vB)
        {
            double[] N        = inp.n;
            double   hCellMin = this.m_LsTrk.GridDat.Cells.h_min[inp.jCell];

            int D = N.Length;

            Debug.Assert(this.ArgumentOrdering.Count == 3);

            double PosCellLengthScale = PosLengthScaleS[inp.jCell];
            double NegCellLengthScale = NegLengthScaleS[inp.jCell];

            double hCutCellMin = Math.Min(NegCellLengthScale, PosCellLengthScale);

            if (hCutCellMin <= 1.0e-10 * hCellMin)
            {
                // very small cell -- clippling
                hCutCellMin = hCellMin;
            }

            Debug.Assert(TA.Length == this.ArgumentOrdering.Count);
            Debug.Assert(TB.Length == this.ArgumentOrdering.Count);


            double res = 0;

            res -= (0.5 * (TA[0] * muA + TB[0] * muB) * N[0] + 0.5 * (TA[1] * muA + TB[1] * muB) * N[1]) * (vA - vB); // central difference for stress divergence
            res += penalty2 / hCellMin * (TA[2] * muA - TB[2] * muB) * (vA - vB);

            return(res);
        }
Пример #9
0
        public double LevelSetForm(ref CommonParamsLs inp, double[] U_Neg, double[] U_Pos, double[,] Grad_uA, double[,] Grad_uB, double vA, double vB, double[] Grad_vA, double[] Grad_vB)
        {
            double FlxNeg = -U_Neg[0] * inp.n[0] * alpha_A;
            double FlxPos = -U_Pos[0] * inp.n[0] * alpha_B;

            return(FlxNeg * vA - FlxPos * vB);
        }
Пример #10
0
        /// <summary>
        /// default-implementation
        /// </summary>
        public double LevelSetForm(ref CommonParamsLs inp,
                                   //public override double EdgeForm(ref Linear2ndDerivativeCouplingFlux.CommonParams inp,
                                   double[] uA, double[] uB, double[,] Grad_uA, double[,] Grad_uB,
                                   double vA, double vB, double[] Grad_vA, double[] Grad_vB)
        {
            double[] N        = inp.n;
            double   hCellMin = this.m_LsTrk.GridDat.Cells.h_min[inp.jCell];

            // symmetric interior penalty
            // ==========================

            int    D = N.Length;
            double Grad_uA_xN = 0, Grad_uB_xN = 0, Grad_vA_xN = 0, Grad_vB_xN = 0;

            for (int d = 0; d < D; d++)
            {
                Grad_uA_xN += Grad_uA[0, d] * N[d];
                Grad_uB_xN += Grad_uB[0, d] * N[d];
                Grad_vA_xN += Grad_vA[d] * N[d];
                Grad_vB_xN += Grad_vB[d] * N[d];
            }

            double NegCellLengthScale = NegCellLengthScaleS[inp.jCell];
            double PosCellLengthScale = PosCellLengthScaleS[inp.jCell];
            double hCutCellMin        = Math.Min(NegCellLengthScale, PosCellLengthScale);

            Debug.Assert(!(double.IsInfinity(hCutCellMin) || double.IsNaN(hCutCellMin)));

            if (hCutCellMin <= 1.0e-10 * hCellMin)
            {
                // very small cell -- clipping
                hCutCellMin = hCellMin;
            }

            double Ret = 0.0;

            Ret -= 0.5 * (m_muA * Grad_uA_xN + m_muB * Grad_uB_xN) * (vA - vB);                                                   // consistency term
            Ret -= 0.5 * (m_muA * Grad_vA_xN + m_muB * Grad_vB_xN) * (uA[0] - uB[0]);                                             // symmetry term
            Ret += (m_penalty / hCutCellMin) * (uA[0] - uB[0]) * (vA - vB) * (Math.Abs(m_muA) > Math.Abs(m_muB) ? m_muA : m_muB); // penalty term


            // moving-mesh-contribution
            // ========================

            double s = m_NormalVel(inp.x, inp.time);
            double movingFlux;

            if (s > 0)   // select DOWN-wind!
            {
                movingFlux = (-s) * uB[0];
            }
            else
            {
                movingFlux = (-s) * uA[0];
            }


            Debug.Assert(!(double.IsInfinity(Ret) || double.IsNaN(Ret)));
            return(Ret);
        }
Пример #11
0
        protected double GetPenalty(ref CommonParamsLs inp)
        {
            //double penaltySizeFactor_A = 1.0 / this.ccBB.Get_hminBB(this.NegativeSpecies, inp.jCell);
            //double penaltySizeFactor_B = 1.0 / this.ccBB.Get_hminBB(this.PositiveSpecies, inp.jCell);
            double penaltySizeFactor_A = 1.0 / inp.NegCellLengthScale;
            double penaltySizeFactor_B = 1.0 / inp.PosCellLengthScale;

            Debug.Assert(!double.IsNaN(penaltySizeFactor_A));
            Debug.Assert(!double.IsNaN(penaltySizeFactor_B));
            Debug.Assert(!double.IsInfinity(penaltySizeFactor_A));
            Debug.Assert(!double.IsInfinity(penaltySizeFactor_B));
            double penaltySizeFactor = Math.Max(penaltySizeFactor_A, penaltySizeFactor_B);


            double penalty_muFactor;

            switch (this.m_mode)
            {
            case Mode.SWIP:
                penalty_muFactor = (2.0 * muA * muB) / (muA + muB);
                break;


            case Mode.SIP:
                //case Mode.VolumeScaled:
                penalty_muFactor = Math.Max(Math.Abs(muA), Math.Abs(muB)) * Math.Sign(muA);
                break;

            default:
                throw new NotImplementedException();
            }

            return(this.penatly_baseFactor * penaltySizeFactor * penalty_muFactor);
        }
Пример #12
0
        public override double LevelSetForm(ref CommonParamsLs inp, double[] U_Neg, double[] U_Pos, double[,] Grad_uA, double[,] Grad_uB, double vA, double vB, double[] Grad_vA, double[] Grad_vB)
        {
            //public override void DerivativVar_LevelSetFlux(out double FlxNeg, out double FlxPos, ref CommonParams input, double[] U_Neg, double[] U_Pos, double[,] GradU_Neg, double[,] GradU_Pos) {
            double FlxNeg = 0; // we are not interested in "A"
            double FlxPos = U_Pos[0] * inp.n[0];

            return(FlxNeg * vA - FlxPos * vB);
        }
Пример #13
0
        /// <summary>
        /// default-implementation
        /// </summary>
        public double LevelSetForm(ref CommonParamsLs inp,
                                   //public override double EdgeForm(ref Linear2ndDerivativeCouplingFlux.CommonParams inp,
                                   double[] uA, double[] uB, double[,] Grad_uA, double[,] Grad_uB,
                                   double vA, double vB, double[] Grad_vA, double[] Grad_vB)
        {
            double[] N        = inp.n;
            double   hCellMin = this.m_LsTrk.GridDat.Cells.h_min[inp.jCell];

            int D = N.Length;

            //Debug.Assert(this.ArgumentOrdering.Count == D);
            Debug.Assert(Grad_uA.GetLength(0) == this.ArgumentOrdering.Count);
            Debug.Assert(Grad_uB.GetLength(0) == this.ArgumentOrdering.Count);
            Debug.Assert(Grad_uA.GetLength(1) == D);
            Debug.Assert(Grad_uB.GetLength(1) == D);

            double Grad_uA_xN = 0, Grad_uB_xN = 0, Grad_vA_xN = 0, Grad_vB_xN = 0;

            for (int d = 0; d < D; d++)
            {
                Grad_uA_xN += Grad_uA[0, d] * N[d];
                Grad_uB_xN += Grad_uB[0, d] * N[d];
                Grad_vA_xN += Grad_vA[d] * N[d];
                Grad_vB_xN += Grad_vB[d] * N[d];
            }

            double PosCellLengthScale = PosLengthScaleS[inp.jCell];
            double NegCellLengthScale = NegLengthScaleS[inp.jCell];

            double hCutCellMin = Math.Min(NegCellLengthScale, PosCellLengthScale);

            Debug.Assert(!(double.IsInfinity(hCutCellMin) || double.IsNaN(hCutCellMin)));

            if (hCutCellMin <= 1.0e-10 * hCellMin)
            {
                // very small cell -- clippling
                hCutCellMin = hCellMin;
            }

            double Ret = 0.0;

            Ret -= 0.5 * (kA * Grad_uA_xN + kB * Grad_uB_xN) * (vA - vB);                           // consistency term
            //Ret -= 0.5 * (kA * Grad_uA_xN + kB * Grad_uB_xN) * (vA - 0);                           // consistency term
            //Ret -= 0.5 * (kA * Grad_uA_xN + kB * Grad_uB_xN) * (0 - vB);                           // consistency term

            Ret -= 0.5 * (kA * Grad_vA_xN + kB * Grad_vB_xN) * (uA[0] - uB[0]);                     // symmetry term
            //Ret -= 0.5 * (kA * Grad_vA_xN + kB * Grad_vB_xN) * (uA[0] - Tsat);                     // symmetry term
            //Ret -= 0.5 * (kA * Grad_vA_xN + kB * Grad_vB_xN) * (Tsat - uB[0]);                     // symmetry term

            Ret += (penalty / hCutCellMin) * (uA[0] - uB[0]) * (vA - vB) * (Math.Abs(kA) > Math.Abs(kB) ? kA : kB); // penalty term
            //Ret += (penalty / hCutCellMin) * (uA[0] - Tsat) * (vA - vB) * (Math.Abs(kA) > Math.Abs(kB) ? kA : kB); // penalty term
            //Ret += (penalty / hCutCellMin) * (Tsat - uB[0]) * (vA - vB) * (Math.Abs(kA) > Math.Abs(kB) ? kA : kB); // penalty term


            Debug.Assert(!(double.IsInfinity(Ret) || double.IsNaN(Ret)));
            return(Ret);
        }
Пример #14
0
        /// <summary>
        /// default-implementation
        /// </summary>
        public double LevelSetForm(ref CommonParamsLs inp,
                                   double[] UA, double[] UB, double[,] Grad_uA, double[,] Grad_uB,
                                   double VA, double VB, double[] Grad_vA, double[] Grad_vB)
        {
            double[] N        = inp.n;
            double   hCellMin = this.m_LsTrk.GridDat.Cells.h_min[inp.jCell];

            int D = N.Length;

            Debug.Assert(this.ArgumentOrdering.Count == 2);

            double PosCellLengthScale = PosLengthScaleS[inp.jCell];
            double NegCellLengthScale = NegLengthScaleS[inp.jCell];

            double hCutCellMin = Math.Min(NegCellLengthScale, PosCellLengthScale);

            if (hCutCellMin <= 1.0e-10 * hCellMin)
            {
                // very small cell -- clippling
                hCutCellMin = hCellMin;
            }

            Debug.Assert(UA.Length == this.ArgumentOrdering.Count);
            Debug.Assert(UB.Length == this.ArgumentOrdering.Count);

            double res = 0;

            switch (Component)
            {
            case 0:
                res += 0.5 * ((UA[0] * betaA + UB[0] * betaB) * N[0] + (UA[1] * betaA + UB[1] * betaB) * N[0]);                 // central difference fo grad(u) and grad(u)^T
                res += pen1[0] * ((UA[0] * betaA - UB[0] * betaB) * N[0]) + pen1[1] * ((UA[0] * betaA - UB[0] * betaB) * N[1]); // beta Penalty for grad(u)
                res += pen1[0] * ((UA[1] * betaA - UB[1] * betaB) * N[0]) + pen1[1] * ((UA[1] * betaA - UB[1] * betaB) * N[1]); // beta penalty for grad(u)^T

                break;

            case 1:
                res += 0.5 * ((UA[0] * betaA + UB[0] * betaB) * N[1] + (UA[1] * betaA + UB[1] * betaB) * N[0]);
                res += pen1[0] * ((UA[0] * betaA - UB[0] * betaB) * N[0]) + pen1[1] * ((UA[0] * betaA - UB[0] * betaB) * N[1]);
                res += pen1[0] * ((UA[1] * betaA - UB[1] * betaB) * N[0]) + pen1[1] * ((UA[1] * betaA - UB[1] * betaB) * N[1]);

                break;

            case 2:
                res += 0.5 * ((UA[0] * betaA + UB[0] * betaB) * N[1] + (UA[1] * betaA + UB[1] * betaB) * N[1]);
                res += pen1[0] * ((UA[0] * betaA - UB[0] * betaB) * N[0]) + pen1[1] * ((UA[0] * betaA - UB[0] * betaB) * N[1]);
                res += pen1[0] * ((UA[1] * betaA - UB[1] * betaB) * N[0]) + pen1[1] * ((UA[1] * betaA - UB[1] * betaB) * N[1]);

                break;

            default:
                throw new NotImplementedException();
            }

            return(-2 * 0.5 * res * (VA - VB));
        }
Пример #15
0
        /// <summary>
        /// default-implementation
        /// </summary>
        public double LevelSetForm(ref CommonParamsLs inp,
                                   double[] uA, double[] uB, double[,] Grad_uA, double[,] Grad_uB,
                                   double vA, double vB, double[] Grad_vA, double[] Grad_vB)
        {
            double[] N        = inp.n;
            double   hCellMin = this.m_LsTrk.GridDat.Cells.h_min[inp.jCell];

            int D = N.Length;

            Debug.Assert(this.ArgumentOrdering.Count == D);
            Debug.Assert(Grad_uA.GetLength(0) == this.ArgumentOrdering.Count);
            Debug.Assert(Grad_uB.GetLength(0) == this.ArgumentOrdering.Count);
            Debug.Assert(Grad_uA.GetLength(1) == D);
            Debug.Assert(Grad_uB.GetLength(1) == D);

            double Grad_uA_xN = 0, Grad_uB_xN = 0, Grad_vA_xN = 0, Grad_vB_xN = 0;

            for (int d = 0; d < D; d++)
            {
                Grad_uA_xN += Grad_uA[component, d] * N[d];
                Grad_uB_xN += Grad_uB[component, d] * N[d];
                Grad_vA_xN += Grad_vA[d] * N[d];
                Grad_vB_xN += Grad_vB[d] * N[d];
            }
            double Ret = 0.0;

            double PosCellLengthScale = PosLengthScaleS[inp.jCell];
            double NegCellLengthScale = NegLengthScaleS[inp.jCell];

            double hCutCellMin = Math.Min(NegCellLengthScale, PosCellLengthScale);

            if (hCutCellMin <= 1.0e-10 * hCellMin)
            {
                // very small cell -- clippling
                hCutCellMin = hCellMin;
            }

            Debug.Assert(uA.Length == this.ArgumentOrdering.Count);
            Debug.Assert(uB.Length == this.ArgumentOrdering.Count);
            //switch (m_ViscosityImplementation) {
            //    // old Form (H-Implementation)
            //    case ViscosityImplementation.H: {
            double muMax = (Math.Abs(muA) > Math.Abs(muB)) ? muA : muB;

            Ret -= 0.5 * (muA * Grad_uA_xN + muB * Grad_uB_xN) * (vA - vB);                                    // consistency term
            Ret -= 0.5 * (muA * Grad_vA_xN + muB * Grad_vB_xN) * M * ((1 / rhoA) - (1 / rhoB)) * N[component]; // symmetry term
            Ret += (penalty / hCutCellMin) * M * ((1 / rhoA) - (1 / rhoB)) * N[component] * (vA - vB) * muMax; // penalty term
                                                                                                               // Transpose Term
            for (int i = 0; i < D; i++)
            {
                Ret -= 0.5 * (muA * Grad_uA[i, component] + muB * Grad_uB[i, component]) * (vA - vB) * N[i];  // consistency term
                Ret -= 0.5 * (muA * Grad_vA[i] + muB * Grad_vB[i]) * N[component] * M * ((1 / rhoA) - (1 / rhoB)) * N[i];
            }

            return(Ret);
        }
Пример #16
0
        /*
         *
         * // Flux over interface
         * public override void DerivativVar_LevelSetFlux(out double FlxNeg, out double FlxPos,
         *  ref CommonParamsLs cp,
         *  double[] U_Neg, double[] U_Pos, double[,] GradU_Neg, double[,] GradU_Pos) {
         *
         *  double[] _uLevSet = new double[2];
         *
         *  //_uLevSet[0] = (uLevSet[m_d])(cp.time, cp.x);
         *
         *  for (int d = 0; d < m_D; d++) {
         *      _uLevSet[d] = (uLevSet[d])(cp.time);
         *  }
         *
         *  double[] uLevSet_temp = new double[1];
         *  uLevSet_temp[0] = (uLevSet[m_d])(cp.time);
         *
         *  BoSSS.Foundation.CommonParams inp; // = default(BoSSS.Foundation.InParams);
         *  inp.Parameters_IN = cp.ParamsNeg;
         *  inp.Normale = cp.n;
         *  inp.iEdge = int.MinValue;
         *  inp.GridDat = this.m_LsTrk.GridDat;
         *  inp.X = cp.x;
         *  inp.time = cp.time;
         *  //inp.jCellIn = cp.jCell;
         *  //inp.jCellOut = cp.jCell;
         *
         *  inp.Parameters_OUT = new double[inp.Parameters_IN.Length];
         *
         *  //Outer values for Velocity and VelocityMean
         *  for (int j = 0; j < m_D; j++) {
         *      inp.Parameters_OUT[j] = (uLevSet[j])(cp.time);
         *      // Velocity0MeanVectorOut is set to zero, i.e. always LambdaIn is used.
         *      inp.Parameters_OUT[m_D + j] = 0;
         *  }
         *
         *  //FlxNeg = -this.NegFlux.IEF(ref inp, U_Neg, uLevSet_temp);
         *
         *  FlxNeg = 0;
         *
         *  FlxPos = 0;
         *
         *
         * }
         */

        public double LevelSetForm(ref CommonParamsLs cp, double[] U_Neg, double[] U_Pos, double[,] Grad_uA, double[,] Grad_uB, double v_Neg, double v_Pos, double[] Grad_vA, double[] Grad_vB)
        {
            double[] _uLevSet = new double[2];



            BoSSS.Foundation.CommonParams inp; // = default(BoSSS.Foundation.InParams);
            inp.Parameters_IN  = cp.ParamsNeg;
            inp.Normale        = cp.n;
            inp.iEdge          = int.MinValue;
            inp.GridDat        = this.m_LsTrk.GridDat;
            inp.X              = cp.x;
            inp.time           = cp.time;
            inp.Parameters_OUT = new double[inp.Parameters_IN.Length];



            //for (int d = 0; d < m_D; d++)
            //{
            //    _uLevSet[d] = (uLevSet[d])(cp.time);
            //}

            double[] uLevSet_temp = new double[1];
            if (m_d == 0)
            {
                uLevSet_temp[0] = (uLevSet[0])(cp.time) + pRadius * wLevSet[0](cp.time) * -cp.n[1];
            }
            else
            {
                uLevSet_temp[0] = (uLevSet[1])(cp.time) + pRadius * wLevSet[0](cp.time) * cp.n[0];
            }

            //Outer values for Velocity and VelocityMean
            inp.Parameters_OUT[0] = (uLevSet[0])(cp.time) + pRadius * wLevSet[0](cp.time) * -cp.n[1];
            inp.Parameters_OUT[1] = (uLevSet[1])(cp.time) + pRadius * wLevSet[0](cp.time) * cp.n[0];
            // Velocity0MeanVectorOut is set to zero, i.e. always LambdaIn is used.
            inp.Parameters_OUT[2] = 0;
            inp.Parameters_OUT[3] = 0;


            double FlxNeg;

            if (m_UseMovingMesh == true)
            {
                FlxNeg = 0;

                return(FlxNeg);
            }

            FlxNeg = this.NegFlux.InnerEdgeForm(ref inp, U_Neg, uLevSet_temp, null, null, v_Neg, 0, null, null);

            //FlxNeg = this.NegFlux.InnerEdgeForm(ref inp, U_Neg, uLevSet_temp, Grad_uA, Grad_uB, v_Neg, v_Pos, Grad_vA, Grad_vB);

            return(FlxNeg);
        }
Пример #17
0
 public double LevelSetForm(ref CommonParamsLs inp, double[] pA, double[] pB, double[,] Grad_pA, double[,] Grad_pB, double vA, double vB, double[] Grad_vA, double[] Grad_vB)
 {
     if (!weighted)
     {
         return(-(vB - vA) * inp.n[m_d] * 0.5 * (pB[0] + pA[0]));
     }
     else
     {
         return(-(vB - vA) * inp.n[m_d] * (wA * pB[0] + wB * pA[0]) / (wA + wB));
     }
 }
Пример #18
0
        /// <summary>
        /// default-implementation
        /// </summary>
        public override double LevelSetForm(ref CommonParamsLs inp,
                                            double[] uA, double[] uB, double[,] Grad_uA, double[,] Grad_uB,
                                            double vA, double vB, double[] Grad_vA, double[] Grad_vB)
        {
            double[] N        = inp.n;
            double   hCellMin = this.m_LsTrk.GridDat.Cells.h_min[inp.jCell];


            double Grad_uA_xN = 0, Grad_uB_xN = 0, Grad_vA_xN = 0, Grad_vB_xN = 0;

            for (int d = 0; d < D; d++)
            {
                Grad_vA_xN += Grad_vA[d] * N[d];
                Grad_vB_xN += Grad_vB[d] * N[d];
            }
            double Ret = 0.0;

            double PosCellLengthScale = PosLengthScaleS[inp.jCell];
            double NegCellLengthScale = NegLengthScaleS[inp.jCell];

            double hCutCellMin = Math.Min(NegCellLengthScale, PosCellLengthScale);

            if (hCutCellMin <= 1.0e-10 * hCellMin)
            {
                // very small cell -- clippling
                hCutCellMin = hCellMin;
            }


            double M = ComputeEvaporationMass(inp.ParamsNeg, inp.ParamsPos, N, inp.jCell);

            if (M == 0.0)
            {
                return(0.0);
            }

            Debug.Assert(uA.Length == this.ArgumentOrdering.Count);
            Debug.Assert(uB.Length == this.ArgumentOrdering.Count);


            double muMax = (Math.Abs(muA) > Math.Abs(muB)) ? muA : muB;

            //Ret -= 0.5 * (muA * Grad_uA_xN + muB * Grad_uB_xN) * (vA - vB);                           // consistency term
            Ret += 0.5 * (muA * Grad_vA_xN + muB * Grad_vB_xN) * M * ((1 / rhoA) - (1 / rhoB)) * N[component]; // symmetry term
            Ret -= (penalty / hCutCellMin) * M * ((1 / rhoA) - (1 / rhoB)) * N[component] * (vA - vB) * muMax; // penalty term
                                                                                                               // Transpose Term
            for (int i = 0; i < D; i++)
            {
                //Ret -= 0.5 * (muA * Grad_uA[i, component] + muB * Grad_uB[i, component]) * (vA - vB) * N[i];  // consistency term
                Ret += 0.5 * (muA * Grad_vA[i] + muB * Grad_vB[i]) * N[component] * M * ((1 / rhoA) - (1 / rhoB)) * N[i];
            }

            return(-Ret);
        }
Пример #19
0
        public double LevelSetForm(ref CommonParamsLs inp,
                                   double[] uA, double[] uB, double[,] Grad_uA, double[,] Grad_uB,
                                   double vA, double vB, double[] Grad_vA, double[] Grad_vB)
        {
            Vector2D V = FlowField(inp.x, inp.ParamsNeg, inp.ParamsPos);
            Vector2D N = new Vector2D(inp.n);

            double s        = m_NormalVel(inp.x, inp.time);
            double RelSpeed = V * N - s;

            /*
             * // static flux contribution
             * // ========================
             * double staticFlux;
             * if (dir >= 0) { // select UP-wind!
             *  staticFlux = (V * N) * uA[0];
             * } else {
             *  staticFlux = (V * N) * uB[0];
             * }
             *
             * // moving-mesh-contribution
             * // ========================
             *
             * double movingFlux;
             * if (dir > 0) { // select DOWN-wind!
             *  movingFlux = (-s) * uB[0];
             * } else {
             *  movingFlux = (-s) * uA[0];
             * }
             *
             * // return
             * // ======
             *
             * return (staticFlux + movingFlux) * (vA - vB);
             */


            // Flux in moving frame
            // ====================

            double Flux;

            if (RelSpeed >= 0)   // UP-wind with respect to relative speed
            {
                Flux = RelSpeed * uA[0];
            }
            else
            {
                Flux = RelSpeed * uB[0];
            }
            return(Flux * (vA - vB));
        }
Пример #20
0
        public double LevelSetForm(ref CommonParamsLs cp, double[] U_Neg, double[] U_Pos, double[,] Grad_uA, double[,] Grad_uB, double v_Neg, double v_Pos, double[] Grad_vA, double[] Grad_vB)
        {
            BoSSS.Foundation.CommonParams inp;

            // Input parameters
            // =============================
            inp.Parameters_IN  = cp.ParamsNeg;
            inp.Normale        = cp.n;
            inp.iEdge          = int.MinValue;
            inp.GridDat        = this.m_LsTrk.GridDat;
            inp.X              = cp.x;
            inp.time           = cp.time;
            inp.Parameters_OUT = new double[inp.Parameters_IN.Length];

            // Particle parameters
            // =============================
            double[] parameters_P = m_getParticleParams(inp.X);
            double[] uLevSet      = new double[] { parameters_P[0], parameters_P[1] };
            double   wLevSet      = parameters_P[2];

            double[] RadialNormalVector = new double[] { parameters_P[3], parameters_P[4] };
            double   RadialLength       = parameters_P[5];
            double   scale = parameters_P[7];

            // Level-set velocity
            // =============================
            double[] uLevSet_temp = new double[1];
            if (m_d == 0)
            {
                uLevSet_temp[0] = (uLevSet[0] + RadialLength * wLevSet * RadialNormalVector[0]);
            }
            else
            {
                uLevSet_temp[0] = (uLevSet[1] + RadialLength * wLevSet * RadialNormalVector[1]);
            }

            // Outer values for Velocity and VelocityMean
            // =============================
            inp.Parameters_OUT[0] = uLevSet[0] + RadialLength * wLevSet * RadialNormalVector[0];
            inp.Parameters_OUT[1] = uLevSet[1] + RadialLength * wLevSet * RadialNormalVector[1];
            // Velocity0MeanVectorOut is set to zero, i.e. always LambdaIn is used.
            inp.Parameters_OUT[2] = 0;
            inp.Parameters_OUT[3] = 0;

            // Computing Flux
            // =============================
            double FlxNeg = m_UseMovingMesh == true
                ? 0                                                                                                           // Moving mesh
                : (this.NegFlux.InnerEdgeForm(ref inp, U_Neg, uLevSet_temp, null, null, v_Neg, 0, null, null)) * (1 - scale); // Splitting

            return(FlxNeg);
        }
Пример #21
0
        public double LevelSetForm(ref CommonParamsLs inp, double[] pA, double[] pB, double[,] Grad_pA, double[,] Grad_pB, double vA, double vB, double[] Grad_vA, double[] Grad_vB)
        {
            if (hVapA > 0.0)
            {
                return((0 - vA) * inp.n[m_d] * pSat);
            }
            else
            {
                return((vB - 0) * inp.n[m_d] * pSat);
            }

            //return (vB - vA) * inp.n[m_d] * pSat;
        }
Пример #22
0
        public double LevelSetForm(ref CommonParamsLs cp, double[] U_Neg, double[] U_Pos, double[,] Grad_uA, double[,] Grad_uB, double v_Neg, double v_Pos, double[] Grad_vA, double[] Grad_vB)
        {
            double[] U_NegFict, U_PosFict;

            this.TransformU(ref U_Neg, ref U_Pos, out U_NegFict, out U_PosFict);

            double[] ParamsNeg = cp.ParamsNeg;
            double[] ParamsPos = cp.ParamsPos;
            double[] ParamsPosFict, ParamsNegFict;
            this.TransformU(ref ParamsNeg, ref ParamsPos, out ParamsNegFict, out ParamsPosFict);
            //Flux for negativ side
            double FlxNeg;
            {
                BoSSS.Foundation.CommonParams inp; // = default(BoSSS.Foundation.InParams);
                inp.Parameters_IN  = ParamsNeg;
                inp.Parameters_OUT = ParamsNegFict;
                inp.Normale        = cp.n;
                inp.iEdge          = int.MinValue;
                inp.GridDat        = this.m_LsTrk.GridDat;
                inp.X    = cp.x;
                inp.time = cp.time;

                FlxNeg = this.NegFlux.IEF(ref inp, U_Neg, U_NegFict);
            }
            // Flux for positive side
            double FlxPos;

            {
                BoSSS.Foundation.CommonParams inp; // = default(BoSSS.Foundation.InParams);
                inp.Parameters_IN  = ParamsPosFict;
                inp.Parameters_OUT = ParamsPos;
                inp.Normale        = cp.n;
                inp.iEdge          = int.MinValue;
                inp.GridDat        = this.m_LsTrk.GridDat;
                inp.X    = cp.x;
                inp.time = cp.time;

                FlxPos = this.PosFlux.IEF(ref inp, U_PosFict, U_Pos);
            }

            if (movingmesh)
            {
                return(0.0);
            }
            else
            {
                return(FlxNeg * v_Neg - FlxPos * v_Pos);
            }
        }
Пример #23
0
        public double LevelSetForm(ref CommonParamsLs cp, double[] uA, double[] uB, double[,] Grad_uA, double[,] Grad_uB, double vA, double vB, double[] Grad_vA, double[] Grad_vB)
        {
            double[] Normal = cp.n;

            double massFlux = -M.Pow2() * ((1 / rhoA) - (1 / rhoB)) * Normal[m_d];

            double FlxNeg = -0.5 * massFlux;
            double FlxPos = +0.5 * massFlux;


            Debug.Assert(!(double.IsNaN(FlxNeg) || double.IsInfinity(FlxNeg)));
            Debug.Assert(!(double.IsNaN(FlxPos) || double.IsInfinity(FlxPos)));

            return(FlxNeg * vA - FlxPos * vB);
        }
        public double LevelSetForm(ref CommonParamsLs inp, double[] uA, double[] uB, double[,] Grad_uA, double[,] Grad_uB, double vA, double vB, double[] Grad_vA, double[] Grad_vB)
        {
            // Convert CommonParamsLs to CommonParams
            CommonParams commonParams;

            commonParams.Normale        = inp.n;
            commonParams.X              = inp.x;
            commonParams.Parameters_IN  = inp.ParamsNeg;
            commonParams.Parameters_OUT = inp.ParamsPos;
            commonParams.iEdge          = int.MaxValue; // Alternative: use cell index as edge index --> Might this cause problems?
            commonParams.GridDat        = this.levelSetTracker.GridDat;
            commonParams.time           = inp.time;

            return(this.bulkFlux.InnerEdgeFormHack(ref commonParams, uA, uB, Grad_uA, Grad_uB, vA, vB, Grad_vA, Grad_vB));
        }
Пример #25
0
        public double LevelSetForm(ref CommonParamsLs inp,
                                   double[] uA, double[] uB, double[,] Grad_uA, double[,] Grad_uB,
                                   double vA, double vB, double[] Grad_vA, double[] Grad_vB)
        {
            Vector N = new Vector(inp.n);

            if (Math.Abs(N * m_Direction - 1.0) >= 1.0e-8)
            {
                throw new ArithmeticException("Normal Vector mismatch.");
            }

            double u0In = inp.ParamsNeg[0];
            double u0Ot = inp.ParamsPos[0];
            double uIn  = uA[0];
            double uOt  = uB[0];

            // interface speed
            double s = m_NormalVel(inp.x, inp.time);

            // shock speed
            double sigma = 0.5 * (u0In + u0Ot);

            sigma = 3.0 / 2.0;

            // Speed of shock relative to interface speed
            double relShockSpeed = sigma - s;

            // upwind-selection
            double uUpwnd, u0Upwnd;

            if (relShockSpeed > 0)
            {
                uUpwnd  = uIn;
                u0Upwnd = u0In;
            }
            else
            {
                uUpwnd  = uOt;
                u0Upwnd = u0Ot;
            }

            // Flux in moving frame (since level-set normal is equal to pseudo-1D-direction 'm_direction', we can drop the normal vectors.
            uUpwnd = u0Upwnd;
            double Flux = (0.5 * u0Upwnd - s) * uUpwnd;

            return(Flux * (vA - vB));
        }
Пример #26
0
        public double LevelSetForm(ref CommonParamsLs cp, double[] uA, double[] uB, double[,] Grad_uA, double[,] Grad_uB, double vA, double vB, double[] Grad_vA, double[] Grad_vB)
        {
            double[] Normal = cp.n;

            Debug.Assert(cp.ParamsPos[m_D + 1] == cp.ParamsNeg[m_D + 1], "curvature must be continuous across interface");
            Debug.Assert(cp.ParamsPos[m_D + 2] == cp.ParamsNeg[m_D + 2], "disjoining pressure must be continuous across interface");

            //double M = ComputeEvaporationMass_Macro(cp.ParamsNeg.GetSubVector(0, m_D), cp.ParamsPos.GetSubVector(0, m_D), Normal);
            //double M = ComputeEvaporationMass_Micro(cp.ParamsNeg[m_D], cp.ParamsPos[m_D], cp.ParamsNeg[m_D + 1], cp.ParamsNeg[m_D + 2]);
            double M = -0.1; // ComputeEvaporationMass(cp.ParamsNeg, cp.ParamsPos, cp.n, evapMicroRegion[cp.jCell]);

            if (M == 0.0)
            {
                return(0.0);
            }

            //Console.WriteLine("mEvap - MassFluxAtInterface: {0}", M);

            double massFlux = M.Pow2() * ((1 / rhoA) - (1 / rhoB)) * Normal[m_d];
            //if(hVapA > 0) {
            //    massFlux *= ((1 / rhoB) - (1 / rhoA)) * Normal[m_d];
            //} else {
            //    massFlux *= ((1 / rhoA) - (1 / rhoB)) * Normal[m_d];
            //}


            double p_disp = cp.ParamsNeg[1];

            // augmented capillary pressure
            //double acp_jump = 0.0;
            //if(!double.IsNaN(p_disp))
            //    acp_jump = massFlux + p_disp;
            //else
            //    acp_jump = massFlux;


            double FlxNeg = -0.5 * massFlux;
            double FlxPos = +0.5 * massFlux;


            Debug.Assert(!(double.IsNaN(FlxNeg) || double.IsInfinity(FlxNeg)));
            Debug.Assert(!(double.IsNaN(FlxPos) || double.IsInfinity(FlxPos)));

            double Ret = FlxNeg * vA - FlxPos * vB;

            return(Ret);
        }
Пример #27
0
        public double LevelSetForm(ref CommonParamsLs inp, double[] pA, double[] pB, double[,] Grad_pA, double[,] Grad_pB, double vA, double vB, double[] Grad_vA, double[] Grad_vB)
        {
            double acc = 0.0;

            if (hVapA > 0.0)
            {
                acc += (0 - vA) * inp.n[m_d] * pSat;
                acc += (vB - 0) * inp.n[m_d] * pB[0];
            }
            else
            {
                acc += (0 - vA) * inp.n[m_d] * pA[0];
                acc += (vB - 0) * inp.n[m_d] * pSat;
            }
            //return (vB - vA) * inp.n[m_d] * pSat;
            return(-acc);
        }
Пример #28
0
        /// <summary>
        ///
        /// </summary>
        public double LevelSetForm(ref CommonParamsLs inp, double[] uA, double[] uB, double[,] Grad_uA, double[,] Grad_uB,
                                   double vA, double vB, double[] Grad_vA, double[] Grad_vB)
        {
            //return (uA[0] - uB[0]) * inp.n[m_d] * (vA - vB);

            double Acc = 0.0;

            if (DirichletCond)
            {
                Acc += 2.0 * (uA[0] - Tsat) * inp.n[m_d] * (vA - 0.0);
                Acc += 2.0 * (Tsat - uB[0]) * inp.n[m_d] * (0.0 - vB);
            }
            else
            {
                Acc += (uA[0] - uB[0]) * inp.n[m_d] * (vA - vB);
            }

            return(Acc);
        }
Пример #29
0
        /// <summary>
        /// The penalty at the interface enforcing phi=0 at the old position
        /// </summary>
        /// <param name="inp"></param>
        /// <param name="uA"></param>
        /// <param name="uB"></param>
        /// <param name="Grad_uA"></param>
        /// <param name="Grad_uB"></param>
        /// <param name="vA"></param>
        /// <param name="vB"></param>
        /// <param name="Grad_vA"></param>
        /// <param name="Grad_vB"></param>
        /// <returns></returns>
        public double LevelSetForm(ref CommonParamsLs inp, double[] uA, double[] uB, double[,] Grad_uA, double[,] Grad_uB, double vA, double vB, double[] Grad_vA, double[] Grad_vB)
        {
            double hmin;

            if (inp.NegCellLengthScale.IsNaN())
            {
                hmin = inp.PosCellLengthScale;
            }
            else if (inp.PosCellLengthScale.IsNaN())
            {
                hmin = inp.NegCellLengthScale;
            }
            else
            {
                hmin = Math.Min(inp.NegCellLengthScale, inp.PosCellLengthScale);
            }

            return(-2 * PenaltyBase / hmin * (uA[0]) * (vA));
        }
Пример #30
0
        public override double LevelSetForm(ref CommonParamsLs cp, double[] uA, double[] uB, double[,] Grad_uA, double[,] Grad_uB, double vA, double vB, double[] Grad_vA, double[] Grad_vB)
        {
            double qEvap = ComputeHeatFlux(cp.ParamsNeg, cp.ParamsPos, cp.n, cp.jCell);

            //Console.WriteLine("qEvap - HeatFluxAtLevelSet: {0}", qEvap);
            if (qEvap == 0.0)
            {
                return(0.0);
            }


            double FlxNeg = qEvap;
            double FlxPos = qEvap;

            Debug.Assert(!(double.IsNaN(FlxNeg) || double.IsInfinity(FlxNeg)));
            Debug.Assert(!(double.IsNaN(FlxPos) || double.IsInfinity(FlxPos)));

            return(FlxNeg * vA - FlxPos * vB);
        }