Exemple #1
0
        public static void ComputeAverageU <T>(IEnumerable <T> U0, VectorField <XDGField> U0mean, int order, XQuadSchemeHelper qh, LevelSetTracker LsTrk) where T : DGField
        {
            using (FuncTrace ft = new FuncTrace()) {
                var    CC     = LsTrk.Regions.GetCutCellMask();
                int    D      = LsTrk.GridDat.SpatialDimension;
                double minvol = Math.Pow(LsTrk.GridDat.Cells.h_minGlobal, D);


                //var qh = new XQuadSchemeHelper(agg);
                foreach (var Spc in LsTrk.SpeciesIdS)  // loop over species...
                //var Spc = this.LsTrk.GetSpeciesId("B"); {
                // shadow fields
                {
                    DGField[] U0_Spc     = U0.Select(U0_d => (U0_d is XDGField) ? ((DGField)((U0_d as XDGField).GetSpeciesShadowField(Spc))) : ((DGField)U0_d)).ToArray();
                    var       U0mean_Spc = U0mean.Select(U0mean_d => U0mean_d.GetSpeciesShadowField(Spc)).ToArray();


                    // normal cells:
                    for (int d = 0; d < D; d++)
                    {
                        U0mean_Spc[d].AccLaidBack(1.0, U0_Spc[d], LsTrk.Regions.GetSpeciesMask(Spc));
                    }

                    // cut cells
                    var scheme = qh.GetVolumeQuadScheme(Spc, IntegrationDomain: LsTrk.Regions.GetCutCellMask());
                    var rule   = scheme.Compile(LsTrk.GridDat, order);
                    CellQuadrature.GetQuadrature(new int[] { D + 1 }, // vector components: ( avg_vel[0], ... , avg_vel[D-1], cell_volume )
                                                 LsTrk.GridDat,
                                                 rule,
                                                 delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) {
                        EvalResult.Clear();
                        for (int d = 0; d < D; d++)
                        {
                            U0_Spc[d].Evaluate(i0, Length, QR.Nodes, EvalResult.ExtractSubArrayShallow(-1, -1, d));
                        }
                        var Vol = EvalResult.ExtractSubArrayShallow(-1, -1, D);
                        Vol.SetAll(1.0);
                    },
                                                 delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) {
                        for (int i = 0; i < Length; i++)
                        {
                            int jCell = i + i0;

                            double Volume = ResultsOfIntegration[i, D];
                            if (Math.Abs(Volume) < minvol * 1.0e-12)
                            {
                                // keep current value
                                // since the volume of species 'Spc' in cell 'jCell' is 0.0, the value in this cell should have no effect
                            }
                            else
                            {
                                for (int d = 0; d < D; d++)
                                {
                                    double IntVal = ResultsOfIntegration[i, d];
                                    U0mean_Spc[d].SetMeanValue(jCell, IntVal / Volume);
                                }
                            }
                        }
                    }).Execute();
                }

#if DEBUG
                {
                    var Uncut = LsTrk.Regions.GetCutCellMask().Complement();


                    VectorField <SinglePhaseField> U0mean_check = new VectorField <SinglePhaseField>(D, new Basis(LsTrk.GridDat, 0), SinglePhaseField.Factory);
                    for (int d = 0; d < D; d++)
                    {
                        U0mean_check[d].ProjectField(1.0, U0.ElementAt(d).Evaluate,
                                                     new CellQuadratureScheme(false, Uncut).AddFixedOrderRules(LsTrk.GridDat, U0.ElementAt(d).Basis.Degree + 1));
                    }

                    foreach (var _Spc in LsTrk.SpeciesIdS)  // loop over species...
                    {
                        for (int d = 0; d < D; d++)
                        {
                            U0mean_check[d].AccLaidBack(-1.0, U0mean[d].GetSpeciesShadowField(_Spc), Uncut.Intersect(LsTrk.Regions.GetSpeciesMask(_Spc)));
                        }
                    }

                    double checkNorm = U0mean_check.L2Norm();
                    Debug.Assert(checkNorm < 1.0e-6);
                }
#endif


                U0mean.ForEach(F => F.CheckForNanOrInf(true, true, true));
            }
        }
 public XOptimizedLaplacianArtificialViscosityFlux_Interface(LevelSetTracker levelSetTracker, string ArgumentVarName, double penaltySafetyFactor, double penaltyFactor, Dictionary <SpeciesId, MultidimensionalArray> inverseLengthScales)
 {
     this.levelSetTracker  = levelSetTracker;
     this.ArgumentOrdering = new string[] { ArgumentVarName };
     this.bulkFlux         = new XOptimizedLaplacianArtificialViscosityFlux(null, levelSetTracker, ArgumentVarName, penaltySafetyFactor, penaltyFactor, inverseLengthScales);
 }
Exemple #3
0
 public TransportFlux_Interface(LevelSetTracker lstrk, Func <double[], double, double> NormalVel)
 {
     m_LsTrk     = lstrk;
     m_NormalVel = NormalVel;
 }
 public EllipticReInitInterfaceForm(double PenaltyBase, LevelSetTracker LSTrk)
 {
     this.PenaltyBase = PenaltyBase;
     this.LSTrk       = LSTrk;
 }
Exemple #5
0
 public LevSetFlx_phi0(LevelSetTracker _LsTrk) : base(_LsTrk)
 {
 }
Exemple #6
0
        //IDictionary<SpeciesId, IEnumerable<double>> Rho {
        //    get {
        //        int D = this.LsTrk.GridDat.SpatialDimension;
        //        double rho_A = 0, rho_B = 0;
        //        this.m_SIMPLEOptions.Control.confSolver.GetExtProperty("rho_A", true, ref rho_A);
        //        this.m_SIMPLEOptions.Control.confSolver.GetExtProperty("rho_B", true, ref rho_B);

        //        double[] _rho_A = new double[D];
        //        _rho_A.SetAll(rho_A);
        //        double[] _rho_B = new double[D];
        //        _rho_B.SetAll(rho_B);

        //        Dictionary<SpeciesId, IEnumerable<double>> R = new Dictionary<SpeciesId, IEnumerable<double>>();
        //        R.Add(this.LsTrk.GetSpeciesId("A"), _rho_A);
        //        R.Add(this.LsTrk.GetSpeciesId("B"), _rho_B);

        //        return R;
        //    }
        //}


        public SIMPLE(LevelSetTracker _LsTrk)
        {
            this.LsTrk = _LsTrk;
        }
 internal ParticleHydrodynamics(LevelSetTracker lsTrk)
 {
     m_LsTrk = lsTrk;
 }
 public HeatFluxAtLevelSet(int _D, LevelSetTracker _LsTrk, ThermalParameters thermParams, double _sigma)
     : base(_D, _LsTrk, thermParams, _sigma)
 {
 }
 /// <summary>
 /// ctor
 /// </summary>
 public CentralDifferencesRHSForm(double PenaltyBase, LevelSetTracker LSTrck) : base(PenaltyBase, LSTrck)
 {
 }
Exemple #10
0
        static public double[] GetParticleForces(VectorField <SinglePhaseField> U, SinglePhaseField P,
                                                 LevelSetTracker LsTrk,
                                                 double muA)
        {
            int D = LsTrk.GridDat.SpatialDimension;
            // var UA = U.Select(u => u.GetSpeciesShadowField("A")).ToArray();
            var UA = U.ToArray();

            int RequiredOrder = U[0].Basis.Degree * 3 + 2;

            //int RequiredOrder = LsTrk.GetXQuadFactoryHelper(momentFittingVariant).GetCachedSurfaceOrders(0).Max();
            //Console.WriteLine("Order reduction: {0} -> {1}", _RequiredOrder, RequiredOrder);

            //if (RequiredOrder > agg.HMForder)
            //    throw new ArgumentException();

            Console.WriteLine("Forces coeff: {0}, order = {1}", LsTrk.CutCellQuadratureType, RequiredOrder);


            ConventionalDGField pA = null;

            //pA = P.GetSpeciesShadowField("A");
            pA = P;

            double[] forces = new double[D];
            for (int d = 0; d < D; d++)
            {
                ScalarFunctionEx ErrFunc = 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), 0, 1);
                    }

                    pA.Evaluate(j0, Len, Ns, pARes);

                    if (LsTrk.GridDat.SpatialDimension == 2)
                    {
                        for (int j = 0; j < Len; j++)
                        {
                            for (int k = 0; k < K; k++)
                            {
                                double acc = 0.0;

                                // pressure
                                switch (d)
                                {
                                case 0:
                                    acc += pARes[j, k] * Normals[j, k, 0];
                                    acc -= (2 * muA) * Grad_UARes[j, k, 0, 0] * Normals[j, k, 0];
                                    acc -= (muA) * Grad_UARes[j, k, 0, 1] * Normals[j, k, 1];
                                    acc -= (muA) * Grad_UARes[j, k, 1, 0] * Normals[j, k, 1];
                                    break;

                                case 1:
                                    acc += pARes[j, k] * Normals[j, k, 1];
                                    acc -= (2 * muA) * Grad_UARes[j, k, 1, 1] * Normals[j, k, 1];
                                    acc -= (muA) * Grad_UARes[j, k, 1, 0] * Normals[j, k, 0];
                                    acc -= (muA) * Grad_UARes[j, k, 0, 1] * Normals[j, k, 0];
                                    break;

                                default:
                                    throw new NotImplementedException();
                                }

                                result[j, k] = acc;
                            }
                        }
                    }
                    else
                    {
                        for (int j = 0; j < Len; j++)
                        {
                            for (int k = 0; k < K; k++)
                            {
                                double acc = 0.0;

                                // pressure
                                switch (d)
                                {
                                case 0:
                                    acc += pARes[j, k] * Normals[j, k, 0];
                                    acc -= (2 * muA) * Grad_UARes[j, k, 0, 0] * Normals[j, k, 0];
                                    acc -= (muA) * Grad_UARes[j, k, 0, 2] * Normals[j, k, 2];
                                    acc -= (muA) * Grad_UARes[j, k, 0, 1] * Normals[j, k, 1];
                                    acc -= (muA) * Grad_UARes[j, k, 1, 0] * Normals[j, k, 1];
                                    acc -= (muA) * Grad_UARes[j, k, 2, 0] * Normals[j, k, 2];
                                    break;

                                case 1:
                                    acc += pARes[j, k] * Normals[j, k, 1];
                                    acc -= (2 * muA) * Grad_UARes[j, k, 1, 1] * Normals[j, k, 1];
                                    acc -= (muA) * Grad_UARes[j, k, 1, 2] * Normals[j, k, 2];
                                    acc -= (muA) * Grad_UARes[j, k, 1, 0] * Normals[j, k, 0];
                                    acc -= (muA) * Grad_UARes[j, k, 0, 1] * Normals[j, k, 0];
                                    acc -= (muA) * Grad_UARes[j, k, 2, 1] * Normals[j, k, 2];
                                    break;

                                case 2:
                                    acc += pARes[j, k] * Normals[j, k, 2];
                                    acc -= (2 * muA) * Grad_UARes[j, k, 2, 2] * Normals[j, k, 2];
                                    acc -= (muA) * Grad_UARes[j, k, 2, 0] * Normals[j, k, 0];
                                    acc -= (muA) * Grad_UARes[j, k, 2, 1] * Normals[j, k, 1];
                                    acc -= (muA) * Grad_UARes[j, k, 0, 2] * Normals[j, k, 0];
                                    acc -= (muA) * Grad_UARes[j, k, 1, 2] * Normals[j, k, 1];
                                    break;

                                default:
                                    throw new NotImplementedException();
                                }

                                result[j, k] = acc;
                            }
                        }
                    }
                };

                var SchemeHelper = LsTrk.GetXDGSpaceMetrics(new[] { LsTrk.GetSpeciesId("A") }, RequiredOrder, 1).XQuadSchemeHelper;
                //var SchemeHelper = new XQuadSchemeHelper(LsTrk, momentFittingVariant, );
                CellQuadratureScheme cqs = SchemeHelper.GetLevelSetquadScheme(0, LsTrk.Regions.GetCutCellMask());

                CellQuadrature.GetQuadrature(new int[] { 1 }, LsTrk.GridDat,
                                             cqs.Compile(LsTrk.GridDat, RequiredOrder), //  agg.HMForder),
                                             delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) {
                    ErrFunc(i0, Length, QR.Nodes, EvalResult.ExtractSubArrayShallow(-1, -1, 0));
                },
                                             delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) {
                    for (int i = 0; i < Length; i++)
                    {
                        forces[d] += ResultsOfIntegration[i, 0];
                    }
                }
                                             ).Execute();
            }

            for (int i = 0; i < D; i++)
            {
                forces[i] = MPI.Wrappers.MPIExtensions.MPISum(forces[i]);
            }

            return(forces);
        }
Exemple #11
0
        /// <summary>
        /// Calculates the drag (x-component) and lift (y-component) forces acting on a cylinder wall of a boundary fitted grid. The definition of the wall is HARDCODED!
        /// </summary>
        static public double[] GetForces_BoundaryFitted(VectorField <SinglePhaseField> GradU, VectorField <SinglePhaseField> GradV, SinglePhaseField StressXX,
                                                        SinglePhaseField StressXY, SinglePhaseField StressYY, SinglePhaseField P, LevelSetTracker LsTrk, double muA, double beta)
        {
            int D = LsTrk.GridDat.SpatialDimension;

            if (D > 2)
            {
                throw new ArgumentException("Method GetForces_BoundaryFitted only implemented for 2D (viscoelastic)!");
            }
            // var UA = U.Select(u => u.GetSpeciesShadowField("A")).ToArray();
            //var UA = U.ToArray();
            MultidimensionalArray Grad_U = new MultidimensionalArray(D);
            var _GradU = GradU.ToArray();
            var _GradV = GradV.ToArray();


            int RequiredOrder = _GradU[0].Basis.Degree * 3 + 2;

            //int RequiredOrder = U[0].Basis.Degree * 3 + 2;
            //int RequiredOrder = LsTrk.GetXQuadFactoryHelper(momentFittingVariant).GetCachedSurfaceOrders(0).Max();
            //Console.WriteLine("Order reduction: {0} -> {1}", _RequiredOrder, RequiredOrder);

            //if (RequiredOrder > agg.HMForder)
            //    throw new ArgumentException();

            Console.WriteLine();
            Console.WriteLine("Forces coeff: {0}, order = {1}", LsTrk.CutCellQuadratureType, RequiredOrder);

            SinglePhaseField _StressXX = StressXX;
            SinglePhaseField _StressXY = StressXY;
            SinglePhaseField _StressYY = StressYY;

            SinglePhaseField pA = null;

            //pA = P.GetSpeciesShadowField("A");
            pA = P;



            double[] forces = new double[D];
            for (int d = 0; d < D; d++)
            {
                ScalarFunctionEx ErrFunc = delegate(int j0, int Len, NodeSet Ns, MultidimensionalArray result) {
                    int K = result.GetLength(1); // No nof Nodes
                    MultidimensionalArray Grad_URes   = MultidimensionalArray.Create(Len, K, D);
                    MultidimensionalArray Grad_VRes   = MultidimensionalArray.Create(Len, K, D);
                    MultidimensionalArray pARes       = MultidimensionalArray.Create(Len, K);
                    MultidimensionalArray StressXXRes = MultidimensionalArray.Create(Len, K);
                    MultidimensionalArray StressXYRes = MultidimensionalArray.Create(Len, K);
                    MultidimensionalArray StressYYRes = MultidimensionalArray.Create(Len, K);

                    var Normals = LsTrk.GridDat.Edges.NormalsCache.GetNormals_Edge(Ns, j0, Len);
                    //var Normals = MultidimensionalArray.Create(1, Ns.Length, 1);
                    //var Normals = LsTrk.GridDat.Edges.NormalsForAffine;


                    for (int i = 0; i < D; i++)
                    {
                        _GradU[i].EvaluateEdge(j0, Len, Ns, Grad_URes.ExtractSubArrayShallow(-1, -1, i),
                                               Grad_URes.ExtractSubArrayShallow(-1, -1, i), ResultIndexOffset: 0, ResultPreScale: 1);

                        _GradV[i].EvaluateEdge(j0, Len, Ns, Grad_VRes.ExtractSubArrayShallow(-1, -1, i),
                                               Grad_VRes.ExtractSubArrayShallow(-1, -1, i), ResultIndexOffset: 0, ResultPreScale: 1);

                        //UA[i].EvaluateGradient(j0, Len, Ns, Grad_UARes.ExtractSubArrayShallow(-1, -1, i, -1), 0, 1);
                    }

                    //pA.Evaluate(j0, Len, Ns, pARes);
                    pA.EvaluateEdge(j0, Len, Ns, pARes, pARes, ResultIndexOffset: 0, ResultPreScale: 1);
                    _StressXX.EvaluateEdge(j0, Len, Ns, StressXXRes, StressXXRes, ResultIndexOffset: 0, ResultPreScale: 1);
                    _StressXY.EvaluateEdge(j0, Len, Ns, StressXYRes, StressXYRes, ResultIndexOffset: 0, ResultPreScale: 1);
                    _StressYY.EvaluateEdge(j0, Len, Ns, StressYYRes, StressYYRes, ResultIndexOffset: 0, ResultPreScale: 1);


                    //if (LsTrk.GridDat.SpatialDimension == 2)
                    //{


                    for (int j = 0; j < Len; j++)
                    {
                        for (int k = 0; k < K; k++)
                        {
                            double acc = 0.0;

                            // pressure
                            switch (d)
                            {
                            case 0:
                                acc += pARes[j, k] * Normals[j, k, 0];
                                acc -= (2 * (muA) * beta) * Grad_URes[j, k, 0] * Normals[j, k, 0];
                                acc -= ((muA) * beta) * Grad_URes[j, k, 1] * Normals[j, k, 1];
                                acc -= ((muA) * beta) * Grad_VRes[j, k, 0] * Normals[j, k, 1];
                                acc -= (muA) * StressXXRes[j, k] * Normals[j, k, 0];
                                acc -= (muA) * StressXYRes[j, k] * Normals[j, k, 1];

                                break;

                            case 1:
                                acc += pARes[j, k] * Normals[j, k, 1];
                                acc -= (2 * (muA) * beta) * Grad_VRes[j, k, 1] * Normals[j, k, 1];
                                acc -= ((muA) * beta) * Grad_VRes[j, k, 0] * Normals[j, k, 0];
                                acc -= ((muA) * beta) * Grad_URes[j, k, 1] * Normals[j, k, 0];
                                acc -= (muA) * StressXYRes[j, k] * Normals[j, k, 0];
                                acc -= (muA) * StressYYRes[j, k] * Normals[j, k, 1];
                                break;

                            default:
                                throw new NotImplementedException();
                            }

                            result[j, k] = acc;
                        }
                    }
                };


                var SchemeHelper = LsTrk.GetXDGSpaceMetrics(new[] { LsTrk.GetSpeciesId("A") }, RequiredOrder, 1).XQuadSchemeHelper;

                //EdgeMask Mask = new EdgeMask(LsTrk.GridDat, "Wall_bottom");
                EdgeMask Mask = new EdgeMask(LsTrk.GridDat, "Wall_cylinder");

                EdgeQuadratureScheme eqs = SchemeHelper.GetEdgeQuadScheme(LsTrk.GetSpeciesId("A"), IntegrationDomain: Mask);

                EdgeQuadrature.GetQuadrature(new int[] { 1 }, LsTrk.GridDat,
                                             eqs.Compile(LsTrk.GridDat, RequiredOrder), //  agg.HMForder),
                                             delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) {
                    ErrFunc(i0, Length, QR.Nodes, EvalResult.ExtractSubArrayShallow(-1, -1, 0));
                },
                                             delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) {
                    for (int i = 0; i < Length; i++)
                    {
                        forces[d] += ResultsOfIntegration[i, 0];
                    }
                }
                                             ).Execute();
            }

            for (int i = 0; i < D; i++)
            {
                forces[i] = MPI.Wrappers.MPIExtensions.MPISum(forces[i]);
            }

            return(forces);
        }
Exemple #12
0
        /// <summary>
        /// modifies a matrix <paramref name="Mtx"/> and a right-hand-side <paramref name="rhs"/>
        /// in order to fix the pressure at some reference point
        /// </summary>
        /// <param name="map">row mapping for <paramref name="Mtx"/> as well as <paramref name="rhs"/></param>
        /// <param name="iVar">the index of the pressure variable in the mapping <paramref name="map"/>.</param>
        /// <param name="LsTrk"></param>
        /// <param name="Mtx"></param>
        /// <param name="rhs"></param>
        static public void SetPressureReferencePoint <T>(UnsetteledCoordinateMapping map, int iVar, LevelSetTracker LsTrk, IMutableMatrixEx Mtx, T rhs)
            where T : IList <double>
        {
            using (new FuncTrace()) {
                var GridDat = map.GridDat;

                if (rhs.Count != map.LocalLength)
                {
                    throw new ArgumentException();
                }
                if (!Mtx.RowPartitioning.EqualsPartition(map) || !Mtx.ColPartition.EqualsPartition(map))
                {
                    throw new ArgumentException();
                }

                Basis PressureBasis = (Basis)map.BasisS[iVar];
                int   D             = GridDat.SpatialDimension;

                long GlobalID, GlobalCellIndex;
                bool IsInside, onthisProc;
                GridDat.LocatePoint(new double[D], out GlobalID, out GlobalCellIndex, out IsInside, out onthisProc,
                                    LsTrk != null ? LsTrk.Regions.GetCutCellSubGrid().VolumeMask.Complement() : null);

                int iRowGl = -111;
                if (onthisProc)
                {
                    //int jCell = (int)GlobalCellIndex - GridDat.CellPartitioning.i0;


                    //NodeSet CenterNode = new NodeSet(GridDat.iGeomCells.GetRefElement(jCell), new double[D]);
                    //MultidimensionalArray LevSetValues = LsTrk.DataHistories[0].Current.GetLevSetValues(CenterNode, jCell, 1); ;


                    //MultidimensionalArray CenterNodeGlobal = MultidimensionalArray.Create(1, D);
                    //GridDat.TransformLocal2Global(CenterNode, CenterNodeGlobal, jCell);
                    //Console.WriteLine("Pressure Ref Point @( {0:0.###E-00} | {1:0.###E-00} )", CenterNodeGlobal[0,0], CenterNodeGlobal[0,1]);


                    //LevelSetSignCode scode = LevelSetSignCode.ComputeLevelSetBytecode(LevSetValues[0, 0]);
                    //ReducedRegionCode rrc;
                    //int No = LsTrk.Regions.GetNoOfSpecies(jCell, out rrc);
                    //int iSpc = LsTrk.GetSpeciesIndex(rrc, scode);

                    iRowGl = (int)map.GlobalUniqueCoordinateIndex_FromGlobal(iVar, GlobalCellIndex, 0);
                }
                iRowGl = iRowGl.MPIMax();


                // clear row
                // ---------
                if (onthisProc)
                {
                    // ref. cell is on local MPI process
                    int jCell = (int)GlobalCellIndex - GridDat.CellPartitioning.i0;

                    //ReducedRegionCode rrc;
                    //int NoOfSpc = LsTrk.Regions.GetNoOfSpecies(jCell, out rrc);

                    // set matrix row to identity
                    Mtx.ClearRow(iRowGl);
                    Mtx.SetDiagonalElement(iRowGl, 1.0);


                    // clear RHS
                    int iRow = iRowGl - Mtx.RowPartitioning.i0;
                    rhs[iRow] = 0;
                }

                // clear column
                // ------------
                {
                    for (int i = Mtx.RowPartitioning.i0; i < Mtx.RowPartitioning.iE; i++)
                    {
                        if (i != iRowGl)
                        {
                            Mtx[i, iRowGl] = 0;
                        }
                    }
                }
            }
        }
Exemple #13
0
        /// <summary>
        /// Calculates the Torque around the center of mass
        /// </summary>
        /// <param name="U"></param>
        /// <param name="P"></param>
        /// <param name="muA"></param>
        /// <param name="particleRadius"></param>
        /// <returns></returns>
        static public double GetTorque(VectorField <SinglePhaseField> U, SinglePhaseField P,
                                       LevelSetTracker LsTrk,
                                       double muA, double particleRadius)
        {
            var _LsTrk = LsTrk;
            int D      = _LsTrk.GridDat.SpatialDimension;
            var UA     = U.ToArray();

            //if (D > 2) throw new NotImplementedException("Currently only 2D cases supported");

            int RequiredOrder = U[0].Basis.Degree * 3;

            //if (RequiredOrder > agg.HMForder)
            //    throw new ArgumentException();

            Console.WriteLine("Torque coeff: {0}, order = {1}", LsTrk.CutCellQuadratureType, RequiredOrder);

            ConventionalDGField pA = null;
            double force           = new double();

            pA = P;

            ScalarFunctionEx ErrFunc = 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), 0, 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;


                        // Calculate the torque around a circular particle with a given radius (Paper Wan and Turek 2005)

                        acc += pARes[j, k] * Normals[j, k, 0];
                        acc -= (2 * muA) * Grad_UARes[j, k, 0, 0] * Normals[j, k, 0];
                        acc -= (muA) * Grad_UARes[j, k, 0, 1] * Normals[j, k, 1];
                        acc -= (muA) * Grad_UARes[j, k, 1, 0] * Normals[j, k, 1];
                        acc *= -Normals[j, k, 1] * particleRadius;


                        acc2 += pARes[j, k] * Normals[j, k, 1];
                        acc2 -= (2 * muA) * Grad_UARes[j, k, 1, 1] * Normals[j, k, 1];
                        acc2 -= (muA) * Grad_UARes[j, k, 1, 0] * Normals[j, k, 0];
                        acc2 -= (muA) * Grad_UARes[j, k, 0, 1] * Normals[j, k, 0];
                        acc2 *= Normals[j, k, 0] * particleRadius;

                        result[j, k] = acc + acc2;
                    }
                }
            };

            var SchemeHelper = LsTrk.GetXDGSpaceMetrics(new[] { LsTrk.GetSpeciesId("A") }, RequiredOrder, 1).XQuadSchemeHelper;
            //var SchemeHelper = new XQuadSchemeHelper(_LsTrk, momentFittingVariant, _LsTrk.GetSpeciesId("A"));
            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(i0, Length, QR.Nodes, EvalResult.ExtractSubArrayShallow(-1, -1, 0));
            },
                                         delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) {
                for (int i = 0; i < Length; i++)
                {
                    force += ResultsOfIntegration[i, 0];
                }
            }

                                         ).Execute();


            return(force);
        }
Exemple #14
0
        /// <summary>
        /// modifies a residual (i.e. an operator evaluation)
        /// in order to fix the pressure at some reference point
        /// </summary>
        /// <param name="currentState">current state of velocity & pressure</param>
        /// <param name="iVar">the index of the pressure variable in the mapping <paramref name="map"/>.</param>
        /// <param name="LsTrk"></param>
        /// <param name="Residual"></param>
        static public void SetPressureReferencePointResidual <T>(CoordinateVector currentState, int iVar, LevelSetTracker LsTrk, T Residual)
            where T : IList <double>
        {
            using (new FuncTrace()) {
                var map     = currentState.Mapping;
                var GridDat = map.GridDat;

                if (Residual.Count != map.LocalLength)
                {
                    throw new ArgumentException();
                }


                Basis PressureBasis = (Basis)map.BasisS[iVar];
                int   D             = GridDat.SpatialDimension;

                long GlobalID, GlobalCellIndex;
                bool IsInside, onthisProc;
                GridDat.LocatePoint(new double[D], out GlobalID, out GlobalCellIndex, out IsInside, out onthisProc, LsTrk.Regions.GetCutCellSubGrid().VolumeMask.Complement());

                int iRowGl = -111;
                if (onthisProc)
                {
                    int jCell = (int)GlobalCellIndex - GridDat.CellPartitioning.i0;


                    NodeSet CenterNode = new NodeSet(GridDat.iGeomCells.GetRefElement(jCell), new double[D]);
                    MultidimensionalArray LevSetValues = LsTrk.DataHistories[0].Current.GetLevSetValues(CenterNode, jCell, 1);;


                    MultidimensionalArray CenterNodeGlobal = MultidimensionalArray.Create(1, D);
                    GridDat.TransformLocal2Global(CenterNode, CenterNodeGlobal, jCell);
                    //Console.WriteLine("Pressure Ref Point @( {0:0.###E-00} | {1:0.###E-00} )", CenterNodeGlobal[0,0], CenterNodeGlobal[0,1]);


                    LevelSetSignCode  scode = LevelSetSignCode.ComputeLevelSetBytecode(LevSetValues[0, 0]);
                    ReducedRegionCode rrc;
                    int No   = LsTrk.Regions.GetNoOfSpecies(jCell, out rrc);
                    int iSpc = LsTrk.GetSpeciesIndex(rrc, scode);

                    iRowGl = (int)map.GlobalUniqueCoordinateIndex_FromGlobal(iVar, GlobalCellIndex, 0);
                }
                iRowGl = iRowGl.MPIMax();


                // clear row
                // ---------
                if (onthisProc)
                {
                    // set entry in residual vector equal to corresponding value in domain vector
                    // (as if the corresponding matrix would have a 1 in the diagonal element and 0 everywhere else)


                    int iRow = iRowGl - map.i0;
                    Residual[iRow] = currentState[iRow];
                }
            }
        }
Exemple #15
0
 public PotentialSolverPrecond(LevelSetTracker _LsTrk)
 {
     this.LsTrk = _LsTrk;
 }
        /// <summary>
        /// ctor for the operator factory, where the equation compnents are set
        /// </summary>
        /// <param name="config"></param>
        /// <param name="_LsTrk"></param>
        /// <param name="_HMFdegree"></param>
        /// <param name="BcMap"></param>
        /// <param name="degU"></param>
        public XRheology_OperatorFactory(XRheology_OperatorConfiguration config, LevelSetTracker _LsTrk, int _HMFdegree, IncompressibleMultiphaseBoundaryCondMap BcMap, int _stressDegree, int degU)
        {
            this.LsTrk = _LsTrk;
            this.D     = _LsTrk.GridDat.SpatialDimension;

            this.HMFDegree = _HMFdegree;

            this.physParams = config.getPhysParams;
            this.dntParams  = config.getDntParams;
            this.useJacobianForOperatorMatrix = config.isUseJacobian;
            this.useArtificialDiffusion       = config.isUseArtificialDiffusion;


            // test input
            // ==========
            {
                if (config.getDomBlocks.GetLength(0) != 3 || config.getCodBlocks.GetLength(0) != 3)
                {
                    throw new ArgumentException();
                }

                //if ((config.getPhysParams.Weissenberg_a <= 0) && (config.getPhysParams.Weissenberg_a <= 0)) {
                //    config.isOldroydB = false;
                //} else {
                //    if ((config.getPhysParams.mu_A <= 0) || (config.getPhysParams.mu_B <= 0))
                //        throw new ArgumentException();
                //}

                //if ((config.getPhysParams.reynolds_A <= 0) && (config.getPhysParams.reynolds_B <= 0)) {
                //    config.isViscous = false;
                //} else {
                //    if ((config.getPhysParams.reynolds_A <= 0) || (config.getPhysParams.reynolds_B <= 0))
                //    throw new ArgumentException();

                //if ((config.getPhysParams.rho_A <= 0) || (config.getPhysParams.rho_B <= 0))
                //    throw new ArgumentException();

                if (_LsTrk.SpeciesNames.Count != 2)
                {
                    throw new ArgumentException();
                }
                if (!(_LsTrk.SpeciesNames.Contains("A") && _LsTrk.SpeciesNames.Contains("B")))
                {
                    throw new ArgumentException();
                }
            }

            // full operator:
            // ==============
            CodName = ArrayTools.Cat(EquationNames.MomentumEquations(this.D), EquationNames.ContinuityEquation, EquationNames.Constitutive(this.D));
            Params  = ArrayTools.Cat(
                VariableNames.Velocity0Vector(this.D),
                VariableNames.Velocity0MeanVector(this.D),
                VariableNames.VelocityX_GradientVector(),
                VariableNames.VelocityY_GradientVector(),
                VariableNames.StressXXP,
                VariableNames.StressXYP,
                VariableNames.StressYYP,
                // "artificialViscosity",
                VariableNames.NormalVector(this.D),
                VariableNames.Curvature,
                VariableNames.SurfaceForceVector(this.D)
                );
            DomName = ArrayTools.Cat(VariableNames.VelocityVector(this.D), VariableNames.Pressure, VariableNames.StressXX, VariableNames.StressXY, VariableNames.StressYY);


            // selected part:
            if (config.getCodBlocks[0])
            {
                CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(0, this.D));
            }
            if (config.getCodBlocks[1])
            {
                CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(this.D, 1));
            }
            if (config.getCodBlocks[2])
            {
                CodNameSelected = ArrayTools.Cat(CodNameSelected, CodName.GetSubVector(this.D + 1, 3));
            }

            if (config.getDomBlocks[0])
            {
                DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(0, this.D));
            }
            if (config.getDomBlocks[1])
            {
                DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(this.D, 1));
            }
            if (config.getDomBlocks[2])
            {
                DomNameSelected = ArrayTools.Cat(DomNameSelected, DomName.GetSubVector(this.D + 1, 3));
            }


            // create Operator
            // ===============
            m_XOp = new XSpatialOperatorMk2(DomNameSelected, Params, CodNameSelected, (A, B, C) => _HMFdegree, this.LsTrk.SpeciesNames);

            // add components
            // ============================

            // species bulk components
            for (int spc = 0; spc < LsTrk.TotalNoOfSpecies; spc++)
            {
                // Navier Stokes equations
                XOperatorComponentsFactory.AddSpeciesNSE(m_XOp, config, this.D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap, LsTrk, out U0meanrequired);

                // continuity equation
                if (config.isContinuity)
                {
                    XOperatorComponentsFactory.AddSpeciesContinuityEq(m_XOp, config, this.D, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap);
                }

                // constitutive equation
                XConstitutiveOperatorComponentsFactory.AddSpeciesConstitutive(m_XOp, config, this.D, stressDegree, LsTrk.SpeciesNames[spc], LsTrk.SpeciesIdS[spc], BcMap, LsTrk, out U0meanrequired);
            }

            //// interface components
            XOperatorComponentsFactory.AddInterfaceNSE(m_XOp, config, this.D, BcMap, LsTrk);                                                          // surface stress tensor
            XOperatorComponentsFactory.AddSurfaceTensionForce(m_XOp, config, this.D, BcMap, LsTrk, degU, out NormalsRequired, out CurvatureRequired); // surface tension force
            XConstitutiveOperatorComponentsFactory.AddInterfaceConstitutive(m_XOp, config, this.D, BcMap, LsTrk, out U0meanrequired);                 //constitutive eq at interfeac

            if (config.isContinuity)
            {
                XOperatorComponentsFactory.AddInterfaceContinuityEq(m_XOp, config, this.D, LsTrk);       // continuity equation
            }
            m_XOp.Commit();
        }
 public ParticleHydrodynamicsIntegration(int spatialDim, VectorField <SinglePhaseField> U, SinglePhaseField P, LevelSetTracker levelSetTracker, CellMask cutCells, double fluidViscosity)
 {
     m_SpatialDim      = spatialDim;
     m_RequiredOrder   = U[0].Basis.Degree * 3 + 2;
     m_U               = U.ToArray();
     m_P               = P;
     m_LevelSetTracker = levelSetTracker;
     m_GridData        = m_LevelSetTracker.GridDat;
     m_CutCells        = cutCells;
     m_FluidViscosity  = fluidViscosity;
 }
Exemple #18
0
 public LinearReconstructionQuadRuleFactory(LevelSetTracker tracker, LineAndPointQuadratureFactory lineAndPointFactory)
 {
     this.tracker     = tracker;
     this.rootFactory = lineAndPointFactory.GetPointFactory();
 }
Exemple #19
0
 public ConvectionInBulk_Localized(int SpatDim, IncompressibleMultiphaseBoundaryCondMap _bcmap, int _component, double _rhoA, double _rhoB, double _LFFA, double _LFFB, LevelSetTracker _lsTrk) : base(SpatDim, _bcmap, _component, _rhoA, _rhoB, _LFFA, _LFFB, _lsTrk)
 {
 }
Exemple #20
0
        /// <summary>
        /// Backup data for some DG field before update of grid.
        /// </summary>
        /// <param name="f"></param>
        /// <param name="Reference">
        /// Unique string reference under which the re-distributed data can be accessed later, within <see cref="RestoreDGField(DGField, string)"/>.
        /// </param>
        override public void BackupField(DGField f, string Reference)
        {
            if (!object.ReferenceEquals(f.GridDat, m_OldGrid))
            {
                throw new ArgumentException("DG field seems to be assigned to some other grid.");
            }
            double[][] oldFieldsData = new double[m_oldJ][];
            m_oldDGFieldData.Add(Reference, oldFieldsData);

            if (f is ConventionalDGField)
            {
                Basis oldBasis = f.Basis;
                int   Nj       = oldBasis.Length;

                for (int j = 0; j < m_oldJ; j++)
                {
                    double[] data_j = new double[Nj];
                    for (int n = 0; n < Nj; n++)
                    {
                        data_j[n] = f.Coordinates[j, n];
                    }

                    FwdTrafo(data_j, Nj, 0, (GridData)m_OldGrid, j, f.Basis.Degree);

                    oldFieldsData[j] = data_j;
                }
            }
            else if (f is XDGField)
            {
                XDGField xf = f as XDGField;
                XDGBasis xb = xf.Basis;
                int      Np = xb.NonX_Basis.Length;
                if (!object.ReferenceEquals(m_OldTracker, xb.Tracker))
                {
                    throw new ArgumentException("LevelSetTracker seems duplicate, or something.");
                }
                LevelSetTracker lsTrk = m_OldTracker;

                for (int j = 0; j < m_oldJ; j++)
                {
                    int NoOfSpc = lsTrk.Regions.GetNoOfSpecies(j);

                    int Nj = xb.GetLength(j);
                    Debug.Assert(Nj == NoOfSpc * Np);

                    double[] data_j = new double[Nj + NoOfSpc + 1];
                    data_j[0] = NoOfSpc;
                    int c = 1;
                    for (int iSpc = 0; iSpc < NoOfSpc; iSpc++)  // loop over species
                    {
                        SpeciesId spc = lsTrk.Regions.GetSpeciesIdFromIndex(j, iSpc);
                        data_j[c] = spc.cntnt;
                        c++;
                        for (int n = 0; n < Np; n++)
                        {
                            data_j[c] = f.Coordinates[j, n + Np * iSpc];
                            c++;
                        }

                        FwdTrafo(data_j, Np, (Np + 1) * iSpc + 2, (GridData)m_OldGrid, j, f.Basis.Degree);
                    }
                    Debug.Assert(data_j.Length == c);

                    oldFieldsData[j] = data_j;
                }
            }
            else
            {
                throw new NotSupportedException();
            }
        }
Exemple #21
0
 public HeatConvectionInBulk(int SpatDim, ThermalMultiphaseBoundaryCondMap _bcmap, double _capA, double _capB, double _LFFA, double _LFFB, LevelSetTracker _lsTrk)
     : base(SpatDim, _bcmap)
 {
     capA = _capA;
     capB = _capB;
     //varMode = _varMode;
     this.lsTrk   = _lsTrk;
     this.LFFA    = _LFFA;
     this.LFFB    = _LFFB;
     this.m_bcmap = _bcmap;
     //base.VelFunction = null;
     base.TempFunction = null;
 }
Exemple #22
0
        /// <summary>
        /// Loads the DG coordinates after grid adaptation.
        /// </summary>
        /// <param name="f"></param>
        /// <param name="Reference">
        /// Unique string reference under which data has been stored before grid-redistribution.
        /// </param>
        public override void RestoreDGField(DGField f, string Reference)
        {
            using (new FuncTrace()) {
                //if(f.Identification == "TestData") {
                //    Console.WriteLine("using oasch");
                //    Oasch = true;
                //} else {
                //    Oasch = false;
                //}



                int      newJ    = this.m_newJ;
                GridData NewGrid = (GridData)m_NewGrid;
                int      pDeg    = f.Basis.Degree; //  Refined_TestData.Basis.Degree;

                if (!object.ReferenceEquals(NewGrid, f.Basis.GridDat))
                {
                    throw new ArgumentException("DG field must be assigned to new grid.");
                }

                f.Clear();

                int[][]      TargMappingIdx = m_Old2NewCorr.GetTargetMappingIndex(NewGrid.CellPartitioning);
                double[][][] ReDistDGCoords = m_newDGFieldData_GridAdapta[Reference];
                Debug.Assert(ReDistDGCoords.Length == newJ);

                if (f is ConventionalDGField)
                {
                    // +++++++++++++++
                    // normal DG field
                    // +++++++++++++++

                    int Np = f.Basis.Length;

                    double[] temp = new double[Np];
                    double[] acc  = new double[Np];

                    for (int j = 0; j < newJ; j++)
                    {
                        if (TargMappingIdx[j] == null)
                        {
                            // unchanged cell
                            Debug.Assert(ReDistDGCoords[j].Length == 1);
                            double[] Coord = ReDistDGCoords[j][0];
                            Debug.Assert(Coord.Length == Np);

                            BckTrafo(Coord, Np, 0, NewGrid, j, pDeg, 1.0);

                            f.Coordinates.SetRow(j, Coord);
                        }
                        else
                        {
                            int L = ReDistDGCoords[j].Length;
                            for (int l = 0; l < L; l++)
                            {
                                DoCellj(j, f, NewGrid, pDeg, TargMappingIdx[j], ReDistDGCoords[j], l, m_Old2NewCorr, 0, 0, Np, temp, acc);
                            }
                        }
                    }
                }
                else if (f is XDGField)
                {
                    // +++++++++++++++++++++++
                    // treatment of XDG fields
                    // +++++++++++++++++++++++

                    // (as always, more difficult)

                    XDGField        xf    = f as XDGField;
                    LevelSetTracker lsTrk = xf.Basis.Tracker;
                    int             Np    = xf.Basis.NonX_Basis.Length;
                    double[]        temp  = new double[Np];
                    double[]        acc   = new double[Np];

                    if (!object.ReferenceEquals(m_NewTracker, lsTrk))
                    {
                        throw new ArgumentException("LevelSetTracker seems duplicate, or something.");
                    }

                    for (int j = 0; j < newJ; j++)
                    {
                        int NoOfSpc = lsTrk.Regions.GetNoOfSpecies(j);
                        f.Coordinates.ClearRow(j);

                        if (TargMappingIdx[j] == null)
                        {
                            // + + + + + + + + +
                            // unchanged cell
                            // + + + + + + + + +

                            Debug.Assert(ReDistDGCoords[j].Length == 1);
                            double[] ReDistDGCoords_jl = ReDistDGCoords[j][0];
                            //Debug.Assert(ReDistDGCoords_jl.Length == NoOfSpc*Np + NoOfSpc + 1);
                            //Debug.Assert(ReDistDGCoords_jl[0] == NoOfSpc);


                            int NoOfSpcR = (int)(ReDistDGCoords_jl[0]); // Number of species received!

                            int c = 1;
                            for (int iSpcR = 0; iSpcR < NoOfSpcR; iSpcR++)  // loop over received species...
                                                                            //#if DEBUG
                                                                            //                                SpeciesId rcvSpc;
                                                                            //                                rcvSpc.cntnt = (int) ReDistDGCoords_jl[c];
                                                                            //                                Debug.Assert(rcvSpc == lsTrk.Regions.GetSpeciesIdFromIndex(j, iSpc));
                                                                            //#endif
                            {
                                SpeciesId rcvSpc;
                                rcvSpc.cntnt = (int)ReDistDGCoords_jl[c];
                                c++;
                                int iSpcTarg = lsTrk.Regions.GetSpeciesIndex(rcvSpc, j);


                                if (iSpcTarg >= 0)
                                {
                                    for (int n = 0; n < Np; n++)
                                    {
                                        f.Coordinates[j, n + Np * iSpcTarg] = ReDistDGCoords_jl[c];
                                        c++;
                                    }
                                }
                                else
                                {
                                    //double testNorm = 0;
                                    for (int n = 0; n < Np; n++)
                                    {
                                        //testNorm += ReDistDGCoords_jl[c].Pow2();
                                        c++;
                                    }
                                }
                            }
                            Debug.Assert(c == ReDistDGCoords_jl.Length);
                        }
                        else
                        {
                            // + + + + + + + + + + + + +
                            // coarsening or refinement
                            // + + + + + + + + + + + + +

                            int L = ReDistDGCoords[j].Length;
                            for (int l = 0; l < L; l++)
                            {
                                double[] ReDistDGCoords_jl = ReDistDGCoords[j][l];
                                int      NoSpcOrg          = (int)ReDistDGCoords_jl[0]; // no of species in original cells

                                int c = 1;
                                for (int iSpcRecv = 0; iSpcRecv < NoSpcOrg; iSpcRecv++)  // loop over species in original cell

                                {
                                    SpeciesId rcvSpc;
                                    rcvSpc.cntnt = (int)ReDistDGCoords_jl[c];
                                    c++;

                                    int iSpc = lsTrk.Regions.GetSpeciesIndex(rcvSpc, j); // species index in new cell
                                    //Debug.Assert(iSpcRecv == iSpc || L > 1);

                                    int N0rcv = c;
                                    c += Np;
                                    if (iSpc >= 0)
                                    {
                                        DoCellj(j, xf, NewGrid, pDeg, TargMappingIdx[j], ReDistDGCoords[j], l, m_Old2NewCorr, N0rcv, Np * iSpc, Np, temp, acc);
                                    }
                                }
                                Debug.Assert(c == ReDistDGCoords_jl.Length);
                            }
                        }
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
        }
Exemple #23
0
 public LevSetFlx(LevelSetTracker _LsTrk)
 {
     m_LsTrk = _LsTrk;
 }
        public FrontTrackingLevelSet2D(VectorField <SinglePhaseField> Velocity_New, VectorField <SinglePhaseField> Velocity_Old, SinglePhaseField Interface, LevelSetTracker InterfaceTrck,
                                       VectorField <SinglePhaseField> LevelSetGradient, int max_AddandAttract_Iteration, int NarrowBandWidth, IGridData Grid, bool LevelSetCorrectionWithNeighbourCells,
                                       int ReseedingInterval, MinimalDistanceSearchMode LevelSetCorrection, TopologyMergingMode TopologyMerging,
                                       NormalVectorDampingMode NormalVectorDamping, double EdgeLengthToCurvatureFraction)

            : base(Velocity_New, Velocity_Old, Interface, InterfaceTrck, LevelSetGradient, NarrowBandWidth, Grid, ReseedingInterval,
                   LevelSetCorrection, TopologyMerging, NormalVectorDamping, 1)
        {
            this.EdgeLengthToCurvatureFraction = EdgeLengthToCurvatureFraction;
        }
Exemple #25
0
            public XDGTestSetup(
                int p,
                double AggregationThreshold,
                int TrackerWidth,
                MultigridOperator.Mode mumo,
                XQuadFactoryHelper.MomentFittingVariants momentFittingVariant,
                ScalarFunction LevSetFunc = null)
            {
                // Level set, tracker and XDG basis
                // ================================

                if (LevSetFunc == null)
                {
                    LevSetFunc = ((_2D)((x, y) => 0.8 * 0.8 - x * x - y * y)).Vectorize();
                }
                LevSet = new LevelSet(new Basis(grid, 2), "LevelSet");
                LevSet.Clear();
                LevSet.ProjectField(LevSetFunc);
                LsTrk = new LevelSetTracker(grid, XQuadFactoryHelper.MomentFittingVariants.Classic, TrackerWidth, new string[] { "A", "B" }, LevSet);
                LsTrk.UpdateTracker();

                XB = new XDGBasis(LsTrk, p);

                XSpatialOperatorMk2 Dummy = new XSpatialOperatorMk2(1, 0, 1, QuadOrderFunc.SumOfMaxDegrees(RoundUp: true), null, "C1", "u");

                //Dummy.EquationComponents["c1"].Add(new
                Dummy.Commit();

                //Tecplot.PlotFields(new DGField[] { LevSet }, "agglo", 0.0, 3);


                // operator
                // ========

                Debug.Assert(p <= 4);
                XDGBasis opXB = new XDGBasis(LsTrk, 4); // we want to have a very precise quad rule
                var      map  = new UnsetteledCoordinateMapping(opXB);

                int quadOrder = Dummy.QuadOrderFunction(map.BasisS.Select(bs => bs.Degree).ToArray(), new int[0], map.BasisS.Select(bs => bs.Degree).ToArray());

                //agg = new MultiphaseCellAgglomerator(new CutCellMetrics(momentFittingVariant, quadOrder, LsTrk, LsTrk.SpeciesIdS.ToArray()), AggregationThreshold, false);
                agg = LsTrk.GetAgglomerator(LsTrk.SpeciesIdS.ToArray(), quadOrder, __AgglomerationTreshold: AggregationThreshold);


                foreach (var S in LsTrk.SpeciesIdS)
                {
                    Console.WriteLine("Species {0}, no. of agglomerated cells {1} ",
                                      LsTrk.GetSpeciesName(S),
                                      agg.GetAgglomerator(S).AggInfo.SourceCells.Count());
                }

                // mass matrix factory
                // ===================

                // Basis maxB = map.BasisS.ElementAtMax(b => b.Degree);
                //MassFact = new MassMatrixFactory(maxB, agg);
                MassFact = LsTrk.GetXDGSpaceMetrics(LsTrk.SpeciesIdS.ToArray(), quadOrder, 1).MassMatrixFactory;


                // Test field
                // ==========

                // set the test field: this is a polynomial function,
                // but different for each species; On this field, restriction followed by prolongation should be the identity
                this.Xdg_uTest = new XDGField(this.XB, "uTest");
                Dictionary <SpeciesId, double> dumia = new Dictionary <SpeciesId, double>();
                int i = 2;

                foreach (var Spc in LsTrk.SpeciesIdS)
                {
                    dumia.Add(Spc, i);
                    i -= 1;
                }
                SetTestValue(Xdg_uTest, dumia);


                // dummy operator matrix which fits polynomial degree p
                // ====================================================

                Xdg_opMtx = new BlockMsrMatrix(Xdg_uTest.Mapping, Xdg_uTest.Mapping);
                Xdg_opMtx.AccEyeSp(120.0);

                // XDG Aggregation BasiseS
                // =======================

                //XAggB = MgSeq.Select(agGrd => new XdgAggregationBasis[] { new XdgAggregationBasis(uTest.Basis, agGrd) }).ToArray();
                XAggB = new XdgAggregationBasis[MgSeq.Length][];
                var _XAggB = AggregationGridBasis.CreateSequence(MgSeq, Xdg_uTest.Mapping.BasisS);

                for (int iLevel = 0; iLevel < XAggB.Length; iLevel++)
                {
                    XAggB[iLevel] = new[] { (XdgAggregationBasis)(_XAggB[iLevel][0]) };
                    XAggB[iLevel][0].Update(agg);
                }

                // Multigrid Operator
                // ==================



                Xdg_opMtx = new BlockMsrMatrix(Xdg_uTest.Mapping, Xdg_uTest.Mapping);
                Xdg_opMtx.AccEyeSp(120.0);

                XdgMultigridOp = new MultigridOperator(XAggB, Xdg_uTest.Mapping,
                                                       Xdg_opMtx,
                                                       MassFact.GetMassMatrix(Xdg_uTest.Mapping, false),
                                                       new MultigridOperator.ChangeOfBasisConfig[][] {
                    new MultigridOperator.ChangeOfBasisConfig[] {
                        new MultigridOperator.ChangeOfBasisConfig()
                        {
                            VarIndex = new int[] { 0 }, mode = mumo, Degree = p
                        }
                    }
                });
            }
Exemple #26
0
 public SingleComponentInterfaceForm(double PenaltyBase, LevelSetTracker LSTrk)
 {
     this.PenaltyBase = PenaltyBase;
     this.LSTrk       = LSTrk;
 }
Exemple #27
0
        /// <summary>
        /// Based on the Ideas by
        /// C. Basting and D. Kuzmin,
        /// “A minimization-based finite element formulation for interface-preserving level set reinitialization”,
        /// Computing, vol. 95, no. 1, pp. 13–25, Dec. 2012.
        /// Create Spatial Operators and build the corresponding Matrices
        /// For the Left-Hand Side of the ReInitProblem
        /// RHS is computed on the fly in <see cref="ReInitSingleStep"/>
        /// The Bulk component is constant unless the grid changes, thus it is computed in <see cref="BuildOperators(CellQuadratureScheme)"/>.
        /// The Interface component changes with its motion.
        /// This component is calculated in <see cref="UpdateOperators(CellQuadratureScheme)"/>.
        /// </summary>
        /// <param name="LSTrck"></param>
        /// <param name="Control">various parameters <paramref name="EllipticReinitControl"/></param>
        /// <param name="HMFOrder">order of tghe interface quadrature</param>
        public EllipticReInit(LevelSetTracker LSTrck, EllipticReInitAlgoControl Control, SinglePhaseField LevelSetForReInit = null)
        {
            this.Control         = Control;
            this.LevelSetTracker = LSTrck;
            if (LevelSetForReInit == null)
            {
                Phi = LevelSetTracker.LevelSets[0] as SinglePhaseField;
            }
            else
            {
                Phi = LevelSetForReInit;
            }
            this.underrelaxation = Control.underrelaxation;

            Residual = new SinglePhaseField(Phi.Basis);
            OldPhi   = new SinglePhaseField(Phi.Basis);
            NewPhi   = new SinglePhaseField(Phi.Basis);
            foreach (SinglePhaseField f in new List <SinglePhaseField> {
                Residual, OldPhi, NewPhi
            })
            {
                f.Clear();
                f.Acc(1.0, Phi);
            }


            this.D = LevelSetTracker.GridDat.SpatialDimension;

            this.ConvergenceCriterion = Control.ConvergenceCriterion;
            this.MaxIteration         = Control.MaxIt;

            double PenaltyBase = ((double)((Phi.Basis.Degree + 1) * (Phi.Basis.Degree + D))) / ((double)D);


            /// Choose Forms according to Upwinding or Central Fluxes
            string[] paramNames;
            int      noOfParamFields;

            IEquationComponent BulkForm;
            RHSForm            myRHSForm;

            LevelSetGradient     = new VectorField <SinglePhaseField>(D, Phi.Basis, "LevelSetGradient", SinglePhaseField.Factory);
            MeanLevelSetGradient = new VectorField <SinglePhaseField>(D, new Basis(Phi.GridDat, 0), "MeanLevelSetGradient", SinglePhaseField.Factory);

            if (Control.Upwinding)
            {
                paramNames      = new string[] { "OldLevelSet", "MeanLevelSetGradient[0]", "MeanLevelSetGradient[1]" };
                noOfParamFields = D;
                LevelSetGradient.Clear();
                LevelSetGradient.Gradient(1.0, Phi);
                //LevelSetGradient.GradientByFlux(1.0, Phi);
                MeanLevelSetGradient.Clear();
                MeanLevelSetGradient.AccLaidBack(1.0, LevelSetGradient);

                parameterFields = ArrayTools.Cat(new SinglePhaseField[] { OldPhi }, MeanLevelSetGradient.ToArray());
                //throw new NotImplementedException("ToDO");
                BulkForm  = new EllipticReInitUpwindForm_Laplace(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck);
                myRHSForm = new EllipticReInitUpwindForm_RHS(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck);

                OldDirection = new double[MeanLevelSetGradient.CoordinateVector.ToArray().Length];
                for (int i = 0; i < MeanLevelSetGradient.CoordinateVector.Length; i++)
                {
                    OldDirection[i] = Math.Sign(MeanLevelSetGradient.CoordinateVector[i]);
                }
                NewDirection = OldDirection.CloneAs();
            }
            else
            {
                paramNames      = new string[] { };
                noOfParamFields = 0;
                parameterFields = new SinglePhaseField[] { };
                BulkForm        = new CentralDifferencesLHSForm(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck.GridDat.Cells.cj);
                myRHSForm       = new CentralDifferencesRHSForm(Control.PenaltyMultiplierFlux * PenaltyBase, LSTrck);
            }


            // SIP for the bulk Phase
            //this.Operator_bulk = new SpatialOperator(1, noOfParamFields, 1, QuadOrderFunc.SumOfMaxDegrees(1, RoundUp: false), variableNames);
            this.Operator_bulk = BulkForm.Operator();



            /// Zero at the Interface
            ///
            /// Calculate Quadrature Order
            Func <int[], int[], int[], int> InterfaceQuadOrder;

            InterfaceQuadOrder = QuadOrderFunc.FixedOrder(Phi.Basis.Degree * 2 + 2);

            /// Generate Interface Operator
            this.Operator_interface = (new EllipticReInitInterfaceForm(Control.PenaltyMultiplierInterface * PenaltyBase, LSTrck)).XOperator(InterfaceQuadOrder);

            // Nonlinear Part on the RHS
            /// switch for the potential functions
            switch (Control.Potential)
            {
            case ReInitPotential.BastingDoubleWell: {
                myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.DoubleWell(d, b));
                break;
            };

            case ReInitPotential.BastingSingleWell: {
                myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.SingleWell(d, b));
                break;
            };

            case ReInitPotential.SingleWellNear: {
                myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.SingleWellNear(d, b));
                break;
            };

            case ReInitPotential.P4DoubleWell: {
                Console.WriteLine("Warning - This Option for Elliptic ReInit does not work well");
                myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.DoubleWellAlternative(d, b));
                break;
            };

            case ReInitPotential.SingleWellOnCutDoubleWellElse: {
                myRHSForm.DiffusionRate = ((d, b) => DiffusionRates.SingleWellOnCutDoubleWellElse(d, b));
                break;
            }
            }
            Operator_RHS = myRHSForm.Operator(QuadOrderFunc.SumOfMaxDegrees(2, RoundUp: true));


            /// The result of the nonlinear part on the rhs is projected on a single-phase field
            RHSField = new SinglePhaseField(Phi.Basis, "RHS");

            OpMatrix = new MsrMatrix(this.Phi.Mapping, this.Phi.Mapping);
            OpAffine = new double[OpMatrix.RowPartitioning.LocalLength];

            /// Matrix and RHS for the Bulk component
            OpMatrix_bulk = new MsrMatrix(this.Phi.Mapping, this.Phi.Mapping);
            OpAffine_bulk = new double[OpMatrix.RowPartitioning.LocalLength];

            /// Matrix and RHS for the Interface Penalty
            OpMatrix_interface = new MsrMatrix(this.Phi.Mapping, this.Phi.Mapping);
            OpAffine_interface = new double[OpMatrix.RowPartitioning.LocalLength];

            // Init Parameter Fields
            OldPhi.Clear();
            OldPhi.Acc(1.0, Phi);

            // Compute Matrices
            UpdateBulkMatrix();
        }
Exemple #28
0
        void SpecialProjection(LevelSetTracker LsTrk, int order, DGField[] Uin, VectorField <SinglePhaseField> Uout)
        {
            var CC   = LsTrk.Regions.GetCutCellMask();
            var gDat = LsTrk.GridDat;

            // get quadrature rules
            // ====================

            //XQuadSchemeHelper H = new XQuadSchemeHelper(LsTrk, MomentFittingVariant);
            var H = LsTrk.GetXDGSpaceMetrics(new[] { LsTrk.GetSpeciesId("A") }, order, 1).XQuadSchemeHelper;
            CellQuadratureScheme                      cqs      = H.GetLevelSetquadScheme(0, CC);
            ICompositeQuadRule <QuadRule>             surfRule = cqs.Compile(gDat, order);
            ICompositeQuadRule <CellBoundaryQuadRule> bndyRule = (new CellBoundaryQuadratureScheme(true, CC.ToGeometicalMask())).Compile(gDat, order);



            // Compute Mass matrix and RHS for the 'strange' projection
            // ========================================================
            int L = CC.NoOfItemsLocally;
            var Q = new QuadratureKernels(Uin, L);

            Q.BlockCnt = 0;
            CellQuadrature.GetQuadrature(
                new int[] { Q.Nnx + Q.D, Q.Nnx },
                gDat,
                surfRule,
                Q.Evaluate, Q.SaveIntegrationResults_surf).Execute();
            Debug.Assert(Q.BlockCnt == L);

            Q.BlockCnt = 0;
            CellBoundaryQuadrature <CellBoundaryQuadRule> .GetQuadrature(
                new int[] { Q.Nnx + Q.D, Q.Nnx },
                gDat,
                bndyRule,
                Q.Evaluate, Q.SaveIntegrationResults_bndy).Execute();

            Debug.Assert(Q.BlockCnt == L);

            // solve the non-diagonal mass matrix systems
            // ==========================================

            int BlkCnt = 0;

            foreach (int jCell in CC.ItemEnum)
            {
                var MassMatrix = Q.MassMatrix.ExtractSubArrayShallow(BlkCnt, -1, -1);
                var RHS        = Q.RHS.ExtractSubArrayShallow(BlkCnt, -1, -1);

                // Die "Massenmatrix" muss nicht unbedingt invbar sein, daher: Least-Squares solve
                MassMatrix.LeastSquareSolve(RHS);

                for (int d = 0; d < Q.D; d++)
                {
                    for (int n = 0; n < Q.Nnx; n++)
                    {
                        Uout[d].Coordinates[jCell, n] = RHS[n, d];
                    }
                }

                BlkCnt++;
            }
        }