예제 #1
0
        static double JumpNorm(DGField f)
        {
            GridData grd      = (GridData)f.GridDat;
            int      D        = grd.SpatialDimension;
            var      e2cTrafo = grd.Edges.Edge2CellTrafos;

            f.MPIExchange();

            double Unorm = 0;

            EdgeQuadrature.GetQuadrature(
                new int[] { D + 1 }, grd,
                (new EdgeQuadratureScheme()).Compile(grd, f.Basis.Degree * 2),
                delegate(int i0, int Length, QuadRule QR, MultidimensionalArray EvalResult) {  // Evaluate
                NodeSet NS = QR.Nodes;
                EvalResult.Clear();
                int NoOfNodes = NS.NoOfNodes;
                for (int j = 0; j < Length; j++)
                {
                    int iEdge    = j + i0;
                    int jCell_IN = grd.Edges.CellIndices[iEdge, 0];
                    int jCell_OT = grd.Edges.CellIndices[iEdge, 1];
                    var uDiff    = EvalResult.ExtractSubArrayShallow(new int[] { j, 0, 0 }, new int[] { j, NoOfNodes - 1, -1 });

                    if (jCell_OT >= 0)
                    {
                        int iTrafo_IN = grd.Edges.Edge2CellTrafoIndex[iEdge, 0];
                        int iTrafo_OT = grd.Edges.Edge2CellTrafoIndex[iEdge, 1];

                        MultidimensionalArray uIN = MultidimensionalArray.Create(1, NoOfNodes);
                        MultidimensionalArray uOT = MultidimensionalArray.Create(1, NoOfNodes);

                        NodeSet NS_IN = NS.GetVolumeNodeSet(grd, iTrafo_IN);
                        NodeSet NS_OT = NS.GetVolumeNodeSet(grd, iTrafo_OT);

                        f.Evaluate(jCell_IN, 1, NS_IN, uIN);
                        f.Evaluate(jCell_OT, 1, NS_OT, uOT);

                        uDiff.Acc(+1.0, uIN);
                        uDiff.Acc(-1.0, uOT);
                    }
                    else
                    {
                        uDiff.Clear();
                    }
                }

                EvalResult.ApplyAll(x => x * x);
            },
                delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) {  // SaveIntegrationResults
                Unorm += ResultsOfIntegration.Sum();
            }).Execute();

            Unorm = Unorm.MPISum();

            return(Unorm.Sqrt());
        }
예제 #2
0
        /// <summary>
        /// Calculates the drag (x-component) and lift (y-component) forces acting on a wall of a boundary fitted grid
        /// </summary>
        /// <param name="U"></param>
        /// <param name="P"></param>
        /// <param name="muA"></param>
        /// <returns></returns>
        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("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 * (1 - beta)) * StressXXRes[j, k] * Normals[j, k, 0];
                                acc -= (muA * (1 - beta)) * 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 * (1 - beta)) * StressXYRes[j, k] * Normals[j, k, 0];
                                acc -= (muA * (1 - beta)) * StressYYRes[j, k] * Normals[j, k, 1];
                                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;

                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);
        }
예제 #3
0
        /// <summary>
        /// Compares the cell surface and the boundary integral.
        /// </summary>
        public static void TestSealing(IGridData gdat)
        {
            int J = gdat.iLogicalCells.NoOfLocalUpdatedCells;

            int[,] E2Clog = gdat.iGeomEdges.LogicalCellIndices;

            //
            // compute cell surface via edge integrals
            //
            MultidimensionalArray CellSurf1 = MultidimensionalArray.Create(J);

            EdgeQuadrature.GetQuadrature(new int[] { 1 },
                                         gdat, new EdgeQuadratureScheme().Compile(gdat, 2),
                                         delegate(int i0, int Length, QuadRule rule, MultidimensionalArray EvalResult) { // evaluate
                EvalResult.SetAll(1.0);
            },
                                         delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { // save results
                for (int i = 0; i < Length; i++)
                {
                    int iEdge   = i + i0;
                    int jCellIn = E2Clog[iEdge, 0];
                    int jCellOt = E2Clog[iEdge, 1];

                    CellSurf1[jCellIn] += ResultsOfIntegration[i, 0];
                    if (jCellOt >= 0 && jCellOt < J)
                    {
                        CellSurf1[jCellOt] += ResultsOfIntegration[i, 0];
                    }
                }
            }).Execute();

            //
            // compute cell surface via cell boundary integrals
            //
            var cbqs = new CellBoundaryQuadratureScheme(false, null);

            foreach (var Kref in gdat.iGeomCells.RefElements)
            {
                cbqs.AddFactory(new StandardCellBoundaryQuadRuleFactory(Kref));
            }

            MultidimensionalArray CellSurf2 = MultidimensionalArray.Create(J);

            CellBoundaryQuadrature <CellBoundaryQuadRule> .GetQuadrature(new int[] { 1 },
                                                                         gdat, cbqs.Compile(gdat, 2),
                                                                         delegate(int i0, int Length, CellBoundaryQuadRule rule, MultidimensionalArray EvalResult) { // evaluate
                EvalResult.SetAll(1.0);
            },
                                                                         delegate(int i0, int Length, MultidimensionalArray ResultsOfIntegration) { // save results
                int NoOfFaces = ResultsOfIntegration.GetLength(1);
                for (int i = 0; i < Length; i++)
                {
                    int jCell = i + i0;
                    for (int iFace = 0; iFace < NoOfFaces; iFace++)
                    {
                        CellSurf2[jCell] += ResultsOfIntegration[i, iFace, 0];
                    }
                }
            }, cs : CoordinateSystem.Physical).Execute();

            //
            // compare
            //
            MultidimensionalArray Err = CellSurf1.CloneAs();

            Err.Acc(-1.0, CellSurf2);
            double ErrNorm = Err.L2Norm();
            double TotSurf = CellSurf1.L2Norm();

            Console.WriteLine("Area Check " + Err.L2Norm());
            Assert.LessOrEqual(ErrNorm / TotSurf, 1.0e-8);

            //for (int j = 0; j < J; j++) {
            //    if (Err[j].Abs() >= 1.0e-6) {
            //        Console.WriteLine("Mismatch between edge area and cell surface area in cell {0}, GlobalId {1}, No. of neighbors {3},  {2:0.####E-00}", j, gdat.CurrentGlobalIdPermutation.Values[j], Err[j], gdat.Cells.CellNeighbours[j].Length);
            //        schas.SetMeanValue(j, 1);
            //    }
            //}
        }
예제 #4
0
        public void UpdateSensorValues(IEnumerable <DGField> fieldSet, ISpeciesMap speciesMap, CellMask cellMask)
        {
            using (new FuncTrace()) {
                DGField fieldToTest = fieldSet.
                                      Where(f => f.Identification == sensorVariable.Name).
                                      Single();

                sensorValues = new SinglePhaseField(
                    new Basis(fieldToTest.GridDat, 0));

                var quadrature = EdgeQuadrature.GetQuadrature(
                    new int[] { 1 },
                    (GridData)fieldToTest.GridDat,
                    new EdgeQuadratureScheme().Compile(fieldToTest.GridDat, 2 * fieldToTest.Basis.Degree),
                    delegate(int e0, int Length, QuadRule QR, MultidimensionalArray EvalResult) {
                    MultidimensionalArray gIn  = MultidimensionalArray.Create(Length, QR.NoOfNodes);
                    MultidimensionalArray gOut = MultidimensionalArray.Create(Length, QR.NoOfNodes);
                    fieldToTest.EvaluateEdge(
                        e0,
                        Length,
                        QR.Nodes,
                        gIn,
                        gOut,
                        MeanValueIN: null,
                        MeanValueOT: null,
                        GradientIN: null,
                        GradientOT: null,
                        ResultIndexOffset: 0,
                        ResultPreScale: 0.0);

                    for (int e = 0; e < Length; e++)
                    {
                        int edge = e + e0;

                        // Check if "out" neighbor exist; ignore boundary edges for now
                        int outCell = fieldToTest.GridDat.iLogicalEdges.CellIndices[edge, 1];
                        if (outCell < 0)
                        {
                            continue;
                        }

                        for (int node = 0; node < QR.NoOfNodes; node++)
                        {
                            double jump = gOut[e, node] - gIn[e, node];
                            double mean = 0.5 * (gOut[e, node] + gIn[e, node]);
                            double s    = jump / mean;
                            if (!double.IsNaN(s))
                            {
                                EvalResult[e, node, 0] = s * s / (Math.Sign(s) * s + 0.001);
                            }
                        }
                    }
                },
                    delegate(int e0, int Length, MultidimensionalArray ResultsOfIntegration) {
                    for (int e = 0; e < Length; e++)
                    {
                        int edge = e + e0;
                        for (int neighbor = 0; neighbor < 2; neighbor++)       // loop over IN/OUT cells
                        {
                            int jCell = fieldToTest.GridDat.iLogicalEdges.CellIndices[edge, neighbor];
                            if (jCell < 0)
                            {
                                break;
                            }

                            sensorValues.Coordinates[jCell, 0] += ResultsOfIntegration[e, 0];
                        }
                    }
                });
                quadrature.Execute();
            }
        }